I am using JWT authentication tokens in an ASP .NET Core Web API application. The tokens are generated by the API itself, not by a third party. I added SignalR sucessfully to the stack, but now I need to authenticate the users that are trying to execute server (Hub) methods. Someone suggested to pass the token in the "qs" property in JavaScript. This will not work for me as our tokens are really large (they contain lots of claims). I tried writing a custom middleware for reading the token from the payload and auto-authenticating the user. The problem is that, when using WebSockets, the middleware is not executed. Any ideas will help.
Asked
Active
Viewed 5,986 times
18
-
Possible duplicate of [SignalR and OpenId Connect](http://stackoverflow.com/questions/40806171/signalr-and-openid-connect) – adem caglin Dec 17 '16 at 05:39
-
2This is not a duplicate, as I can't use the Query String at all, my tokens are too long and I get a 414 error. I want to build something like a custom middleware that extracts the token from the SignalR message and then logs the user in. – Alin Florin Dec 17 '16 at 08:11
-
Unfortunately there are only two ways of passing the token---either query string or as a parameter. Hopefully this will be addressed in the next version of SignalR. – mikebridge Mar 02 '17 at 22:58
-
maybe header value? – ArkadyB Mar 17 '17 at 13:39
-
2SignalR JS library provided by MS doesn't support setting headers – Alin Florin Mar 17 '17 at 15:46
1 Answers
9
Have a look at article that suggests to use query string Authenticate against a ASP.NET Core 1.0 (vNext) SignalR application using JWT. I know that your token is too long, but author explains how to use middleware to authenticate the request.
Here is the summary from the article:
- SignalR does not have any special authentication mechanism built in, it is using the standard ASP.NET authentication.
- JWT is typically sent in the Authorization header of a request
- The SignalR JavaScript client library does not include the means to send headers in the requests, it does however allow you to pass a query string
- If we pass the token in the query string we can write a middleware that adds a authorization header with the token as its value. This must be done before the Jwt middleware in the pipeline
- Be aware of the “Bearer ” format
I have highlighted the key point that your custom middleware should be registered before Jwt middleware.
From this answer you can create a WebSocket connection and pass your token as basic auth parameter:
var ws = new WebSocket($"ws://{token}@example.com/service");

Andrii Litvinov
- 12,402
- 3
- 52
- 59
-
-
I understand that you qs is long. Can you embed the token into payload and use the middleware to decode it of you register it earlier? – Andrii Litvinov Mar 17 '17 at 15:48
-
Alright, I think you might not have access to the payload in the middleware before SignalR. In that case you can implement custom parser for the token in your application code when you read the payload. You won't be able you use Authorize attribute, but you will be able to check user's claims and all that. – Andrii Litvinov Mar 17 '17 at 15:54
-
Fixed it using ugly hack for now, gzipped the token and shortened the claims names – Alin Florin Mar 17 '17 at 15:57
-
Also have a look at this answer for a hack with basic auth http://stackoverflow.com/a/41521871/2138959. You will still need to implement custom middleware, but token can be passed through header. Which is more secure that query string. – Andrii Litvinov Mar 17 '17 at 16:16
-
-
Thanks! To clarify, "before the Jwt middleware in the pipeline" means add it before app.UseAuthentication(); – Jonathan Brown Oct 24 '18 at 21:12