Open HappyNomad opened 5 years ago
The doc was specifically talking about browsers. It does not apply to the .NET Client as that does not run in a browser.
We can probably make that more clear.
Upon rereading my question right after posting it, the word browser in the quote jumped out at me. I see it now, thanks. But yes, please make it clearer.
Am I the only one who is concerned with sending a token in a query string? This is huge security issue, unless I am missing something?
@kirill-chilingarashvili You're not the only one. I saw related discussion on SignalR Core's dev repo. Look over there. While not ideal, remember that at least it's encrypted by TLS.
Having bearer tokens part of query string is not just bad from the standpoint of web security, but also from server side logging. Most WebServers are by default configured to log the URL along with query string in the logs, which poses a huge risk of spilling bearer tokens in the logs. It would be a great if there is a better alternative than cookie authentication.
@BrennanConroy Now that we have running .NET Client in the browser, shouldn't we expect the same behavior as for the javascript client? I see no query parameter passed to the hub
I think you're referring to https://github.com/dotnet/aspnetcore/issues/18697
Followed the above instructions to set up bearer authentication for a .net signalr core client and was getting 401 unathorized. After some debugging, found out that the token was being sent through the authorization header and not the query string. Then tried to set the context.Token from the authorization header and was now getting a 500 internal error. Finally, it worked when I stripped the Bearer from the token that I got from the authorization header. Did something changed that made the above instruction not work?
You don't need to touch the context.Token
if the token is already present in the authorization header. The auth middleware will automatically look there. The sample code in the doc shows setting the token only if the query string "access_token" is set which is needed in some cases in the browser due to browser APIs not allowing the authorize header to be set.
Thank you. It still works when I commented out setting the context.Token. I would also like to mention that I had to set the [Authorize(AuthenticationSchemes = AzureADDefaults.JwtBearerAuthenticationScheme)] in my hub to make it work. Otherwise I am getting the "Invalid negotiation response received error" on the client.
This cost me a lot hours trying to make it work. I have an Angular Client which I have implemented JWT Auth and created a Gateway whereas it also includes the Identity Service. I have following:
Angular Client: this.connection = new signalR.HubConnectionBuilder() .withUrl("localhost:2", { accessTokenFactory: () => this.loginToken }) .build();
Gateway: localhost:1 Api1: localhost:2 (contains signalR hub) Api2: localhost:3 (contains signalR hub)
I have followed the document from Microsoft but unable to make it work. (https://docs.microsoft.com/en-us/aspnet/core/signalr/authn-and-authz?view=aspnetcore-3.0)
I had even added a middleware from the Gateway, just to add the Bearer Token from the Request in Gateway to Api1 and Api2, but still not working.
I also added Authorize attribute from the Hub class.
As a temporary solution. I had made the Api1 and Api2 hostname public and consume this directly from Angular Client.
Not working: Angular Client-> Gateway -> Api1 Angular Client-> Gateway -> Api2
Working: Angular Client-> Api1 Angular Client-> Api2
This is not the appropriate way because it bypassed the gateway. I had to make a fast solution because I have a tight deadline. Hope there is an alternative way similar to my case? :)
The Bearer token authentication section says:
The doc then continues with an entire
ConfigureServices
method implementation from a sample app.I configured my .NET client app to provide a token, and it's correctly doing so, but I see it's arriving at the hub in the authentication header. I confirmed the connection is using WebSockets as the transport. The token isn't in the query string as the doc says. Without adding any of the bits from the doc's sample
ConfigureServices
method implementation, the claims are available in the hub.That's nice it worked, but it's also confusing since I don't understand why it worked. Why do the docs say I must "Read the token out of the query string", and provide code for doing so, but it's unnecessary in my case. Is my scenario somehow unusual?
I'm using Azure AD B2C so my
ConfigureServices
method resembles the one in the Asp.Net Core 2.2 template for "Individual Accounts" authentication. I wasn't sure which part from the sampleConfigureServices
implementation I'd need, so I got started by adding theAuthorize
attribute to my SignalR Core hub. I expected an auth exception to be thrown, but there wasn't one! The claims are populated, without any of the configuration shown in the doc.Document Details
⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.