Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 
dselgo_eidex
Partner - Creator III
Partner - Creator III

"Ticket retrieval failed" when trying to access Qlik Sense through .NET SDK

Hello, I am trying to connect my web API to our Qlik Sense server using the .NET SDK. I am connecting with AsNtlmUserViaProxy() and passing in the username and password for the service account that installed Qlik Sense on the machine. I am using the code below to connect to Qlik Sense: 

 

ILocation location = Location.FromUri("https://myqliksensesite.com");

await location.AsNtlmUserViaProxyAsync(proxyUsesSsl: true, loginCredentials: new NetworkCredential(
    "username",
    "password",
    "domain"
));

using(var hub = await location.HubAsync())
{
    var engineVersion = await hub.EngineVersionAsync();
    Console.WriteLine($"Engine Version: {engineVersion.ComponentVersion}");
};

 

This works when I try running my web API on my laptop through Visual Studio. It connects to my Qlik Sense server, gets the engine version, and prints it out. However, whenever I try running it on our QA server, it fails with the following error:

 

   AggregateException
   One or more errors occurred. (Ticket retrieval failed.) (Ticket retrieval failed.) (Ticket retrieval failed.) (Ticket retrieval failed.)
   at Qlik.Sense.JsonRpc.RpcConnection.RepeatAttempt(Int32 maxAttempts, Func`2 f, CancellationToken token)
   at Qlik.Sense.JsonRpc.RpcConnection.OpenAsync(CancellationToken token)
   at Qlik.Sense.JsonRpc.RpcConnection.EnsureConnectionIsOpen()
   at Qlik.Sense.JsonRpc.RpcConnection.SendAsync(Request request, TaskCompletionSource`1 tcs)
   at Qlik.Engine.Communication.QlikConnection.PingAsync()
   at Qlik.Engine.LocationExtensions.DisposeOnErrorAsync(IDisposable o, Func`1 f)
   at Qlik.Engine.LocationExtensions.HubAsync(ILocation location, ISession session)

 

Just a little extra information: our QA server is currently running in a Docker container on a Linux server that is running on the same network as our Qlik Sense server. I have whitelisted the IP address of the Linux server in the QMC.

What I'm trying to figure out is what this "Ticket retrieval failed" error means. Does it mean that I am not establishing any connection at all with Qlik Sense, or does it mean that Qlik Sense is rejecting my credentials. If the latter is the case, then why is it working when I run it from my laptop and not on our QA deployment?

1 Solution

Accepted Solutions
Øystein_Kolsrud
Employee
Employee

Follow the message! This might be what you're looking for: https://github.com/dotnet/runtime/issues/31579

View solution in original post

10 Replies
Øystein_Kolsrud
Employee
Employee

"Ticket retrieval failed" means that the call the SDK makes during redirect failed for some reason. If you active a DebugConsole, then you should see the following type of message:

 

[2020-Oct-12T19:03:24.785] OPENING WEBSOCKET CONNECTION 19575591
[2020-Oct-12T19:03:25.084] HANDLING REDIRECT:
{
  "jsonrpc": "2.0",
  "method": "OnAuthenticationInformation",
  "params": {
    "loginUri": "https://<your url>/internal_windows_authentication/?targetId=<GUID>",
    "mustAuthenticate": true
  }
}

 

This is a response you get from the Proxy when you first set up the connection. The SDK does an HTTP GET to that login URI in order to get a ticket. It is that call to the authentication module that fails for some reason in your case.

Can't really say why it's failing though. Especially since it seems to work in your other environment. Perhaps there's some system library missing in your docker instance? The SDK relies on System.Net.Http for the Http request part, so that might be something to look for.

You can also try to see if you can get this example working:

https://github.com/kolsrud/qlik_rest_sdk/blob/master/Qlik.Sense.RestClient/Examples/BasicConnection/...

That library uses a similar approach to authentication as the SDK.

dselgo_eidex
Partner - Creator III
Partner - Creator III
Author

So I was pulled onto a different project for a couple of weeks and I finally got a chance to get back to this. It took me a little while to figure out that DebugConsole was a class from the SDK, but I managed to get an output of the websocket (below):

[2020-Oct-29T21:31:45.563] OPENING WEBSOCKET CONNECTION 50280062
[2020-Oct-29T21:31:45.632] HANDLING REDIRECT:
{
  "jsonrpc": "2.0",
  "method": "OnAuthenticationInformation",
  "params": {
    "loginUri": "https://myurl.com/internal_windows_authentication/?targetId=5c4541ee-8622-4a66-ac6e-c1a38e77ef6e",
    "mustAuthenticate": true
  }
}
[2020-Oct-29T21:31:45.690] ### Failed attempt 1 ### 50280062
[2020-Oct-29T21:31:45.690] ### Failure message: Ticket retrieval failed.
[2020-Oct-29T21:31:45.708] ### Failure stack:    at Qlik.Sense.JsonRpc.WebSocket.SystemNetWebSocketSession.RedirectionPerformed(ConnectionSettings connectionSettings, WebSocket theSocket, Action`1 onMessage, CancellationToken token)
   at Qlik.Sense.JsonRpc.WebSocket.SystemNetWebSocketSession.Open(ConnectionSettings connectionSettings, Action`1 log, CancellationToken token)
   at Qlik.Sense.JsonRpc.WebSocketSessionContainer.OpenAsync(Action`1 onMessage, Action`1 onError, CancellationToken cancellationToken)
   at Qlik.Sense.JsonRpc.RpcConnection.WithTimeout[T](Func`1 func, Int32 timeout, CancellationToken token)
   at Qlik.Sense.JsonRpc.RpcConnection.RepeatAttempt(Int32 maxAttempts, Func`2 f, CancellationToken token)
[2020-Oct-29T21:31:46.578] HANDLING REDIRECT:
{
  "jsonrpc": "2.0",
  "method": "OnAuthenticationInformation",
  "params": {
    "loginUri": "https://myurl.com/internal_windows_authentication/?targetId=8a714e62-d147-4b3f-b57e-3b2154b5c483",
    "mustAuthenticate": true
  }
}
[2020-Oct-29T21:31:46.596] ### Failed attempt 2 ### 50280062
[2020-Oct-29T21:31:46.596] ### Failure message: Ticket retrieval failed.
[2020-Oct-29T21:31:46.597] ### Failure stack:    at Qlik.Sense.JsonRpc.WebSocket.SystemNetWebSocketSession.RedirectionPerformed(ConnectionSettings connectionSettings, WebSocket theSocket, Action`1 onMessage, CancellationToken token)
   at Qlik.Sense.JsonRpc.WebSocket.SystemNetWebSocketSession.Open(ConnectionSettings connectionSettings, Action`1 log, CancellationToken token)
   at Qlik.Sense.JsonRpc.WebSocketSessionContainer.OpenAsync(Action`1 onMessage, Action`1 onError, CancellationToken cancellationToken)
   at Qlik.Sense.JsonRpc.RpcConnection.WithTimeout[T](Func`1 func, Int32 timeout, CancellationToken token)
   at Qlik.Sense.JsonRpc.RpcConnection.RepeatAttempt(Int32 maxAttempts, Func`2 f, CancellationToken token)
[2020-Oct-29T21:31:46.607] HANDLING REDIRECT:
{
  "jsonrpc": "2.0",
  "method": "OnAuthenticationInformation",
  "params": {
    "loginUri": "https://myurl.com/internal_windows_authentication/?targetId=d91fcf91-8ca2-4f6e-9130-d073f758fce7",
    "mustAuthenticate": true
  }
}
[2020-Oct-29T21:31:46.622] ### Failed attempt 3 ### 50280062
[2020-Oct-29T21:31:46.622] ### Failure message: Ticket retrieval failed.
[2020-Oct-29T21:31:46.623] ### Failure stack:    at Qlik.Sense.JsonRpc.WebSocket.SystemNetWebSocketSession.RedirectionPerformed(ConnectionSettings connectionSettings, WebSocket theSocket, Action`1 onMessage, CancellationToken token)
   at Qlik.Sense.JsonRpc.WebSocket.SystemNetWebSocketSession.Open(ConnectionSettings connectionSettings, Action`1 log, CancellationToken token)
   at Qlik.Sense.JsonRpc.WebSocketSessionContainer.OpenAsync(Action`1 onMessage, Action`1 onError, CancellationToken cancellationToken)
   at Qlik.Sense.JsonRpc.RpcConnection.WithTimeout[T](Func`1 func, Int32 timeout, CancellationToken token)
   at Qlik.Sense.JsonRpc.RpcConnection.RepeatAttempt(Int32 maxAttempts, Func`2 f, CancellationToken token)
[2020-Oct-29T21:31:46.633] HANDLING REDIRECT:
{
  "jsonrpc": "2.0",
  "method": "OnAuthenticationInformation",
  "params": {
    "loginUri": "https://myurl.com/internal_windows_authentication/?targetId=c9cf46de-30b8-484b-9c0c-e73c6edc5de1",
    "mustAuthenticate": true
  }
}
[2020-Oct-29T21:31:46.650] ### Failed attempt 4 ### 50280062
[2020-Oct-29T21:31:46.650] ### Failure message: Ticket retrieval failed.
[2020-Oct-29T21:31:46.650] ### Failure stack:    at Qlik.Sense.JsonRpc.WebSocket.SystemNetWebSocketSession.RedirectionPerformed(ConnectionSettings connectionSettings, WebSocket theSocket, Action`1 onMessage, CancellationToken token)
   at Qlik.Sense.JsonRpc.WebSocket.SystemNetWebSocketSession.Open(ConnectionSettings connectionSettings, Action`1 log, CancellationToken token)
   at Qlik.Sense.JsonRpc.WebSocketSessionContainer.OpenAsync(Action`1 onMessage, Action`1 onError, CancellationToken cancellationToken)
   at Qlik.Sense.JsonRpc.RpcConnection.WithTimeout[T](Func`1 func, Int32 timeout, CancellationToken token)
   at Qlik.Sense.JsonRpc.RpcConnection.RepeatAttempt(Int32 maxAttempts, Func`2 f, CancellationToken token)
[2020-Oct-29T21:31:46.651] ### Disposing ### 50280062

It is also worth noting that one difference between my local environment and out QA server is that the latter is behind a nginx reverse proxy. I tried tinkering with that to see if it was keeping the websocket from forming, but I started getting the following error instead:

   AggregateException
   One or more errors occurred. (Unable to establish websocket connection.) (Unable to establish websocket connection.) (Unable to establish websocket connection.) (Unable to establish websocket connection.)
   at Qlik.Sense.JsonRpc.RpcConnection.RepeatAttempt(Int32 maxAttempts, Func`2 f, CancellationToken token)
   at Qlik.Sense.JsonRpc.RpcConnection.OpenAsync(CancellationToken token)
   at Qlik.Sense.JsonRpc.RpcConnection.EnsureConnectionIsOpen()
   at Qlik.Sense.JsonRpc.RpcConnection.SendAsync(Request request, TaskCompletionSource`1 tcs)
   at Qlik.Engine.Communication.QlikConnection.PingAsync()
   at Qlik.Engine.LocationExtensions.DisposeOnErrorAsync(IDisposable o, Func`1 f)
   at Qlik.Engine.LocationExtensions.HubAsync(ILocation location, ISession session)

This leads me to believe that the "Ticket retrieval failed" error occurs AFTER the websocket connection has been established, so it might not be the reverse proxy blocking the websocket, but I could be wrong.

I am going to try the rest_sdk, but I am curious if there is a way to interact with the engine service with plain HTTP requests instead of establishing a websocket?

dselgo_eidex
Partner - Creator III
Partner - Creator III
Author

Tried the RestClient, same thing but with a different error message. It works locally, but fails on our QA server.

var restClient = new RestClient("https://myurl.com");
restClient.AsNtlmUserViaProxy(credentials: new NetworkCredential(
    "username",                   
    "password",              
    "domain"
));

Console.WriteLine(restClient.Get("/qrs/about"));
   AggregateException	
   One or more errors occurred. (GSSAPI operation failed with error - An unsupported mechanism was requested (Unknown error).)
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at Qlik.Sense.RestClient.RestClient.Get(String endpoint)

 

Øystein_Kolsrud
Employee
Employee

Follow the message! This might be what you're looking for: https://github.com/dotnet/runtime/issues/31579

Øystein_Kolsrud
Employee
Employee

dselgo_eidex
Partner - Creator III
Partner - Creator III
Author

Ok, it took a little while to make that change to Docker but I did get a different error this time:

   AggregateException
   One or more errors occurred. (No support for channel binding on operating systems other than Windows.)
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at Qlik.Sense.RestClient.RestClient.Get(String endpoint)
Øystein_Kolsrud
Employee
Employee

This problem seems to be a .NET Core issue: https://github.com/dotnet/runtime/issues/28532

According to that thread it has been fixed in later versions of .NET Core: https://github.com/dotnet/runtime/issues/28532#issuecomment-504847859

 

 

dselgo_eidex
Partner - Creator III
Partner - Creator III
Author

Yup, I saw that as well. I am currently trying to upgrade to .NET 3.1. I'll let you know if that fixes it.

dselgo_eidex
Partner - Creator III
Partner - Creator III
Author

Yup, that was it! I needed to add the gss-ntlmssp library to make it work, and I needed to upgrade to .NET Core 3.1 in order to install it. Both the RestClient and .NET SDK are working fine now.

Thank you so much @Øystein_Kolsrud for taking the time to help me out on this!