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.
18
votes
Possible duplicate of SignalR and OpenId Connect
– adem caglin
This 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
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
maybe header value?
– ArkadyB
SignalR JS library provided by MS doesn't support setting headers
– Alin Florin
1 Answers
9
votes
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");