question

Maxima-5691 avatar image
0 Votes"
Maxima-5691 asked Maxima-5691 edited

SignalR auth - How to access IdentityServer4 token in Angular?

I have an Angular SPA asp.net core app with Identity built from microsoft template dotnet new angular --auth Individual. the authorization and authentication works fine with controllers out of the box. however I spent hours trying to do the same with SignalR hub and am I sitll nowhere.

  1. I feel it should work out of the box but it doesnt. If I put [Authorize] attribute on the Hub class it doesnt connect: "DenyAnonymousAuthorizationRequirement: Requires an authenticated user."

  2. If I remove that attribute - everything works fine but if I try to send messages to certain users only using hub.Clients.User(userId) it doesnt work - as SignalR incoming connection have empty Claims and User objects.

  3. The closes I got to solving it (which is almost nowhere) is to use HubConnectionBuilder options.accessTokenFactory - in that case IdentityServer tries to auth the token.. But the token I passed is fake. I have no idea where to get it on the client (Angular). I use @microsoft/signalr package

Any ideas?

Startup:

 services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
 .AddEntityFrameworkStores<AppDbContext>();
    
 services.AddIdentityServer()
 .AddApiAuthorization<ApplicationUser, AppDbContext>();
    
 services.AddAuthentication()
 .AddIdentityServerJwt()
 .AddCookie(o => { o.SlidingExpiration = false; o.ExpireTimeSpan = TimeSpan.FromMinutes(2); }); // TODO X
    
 services.AddAuthorization();
    
 services.AddSignalR();

 . . .
    
 app.UseAuthentication();
 app.UseIdentityServer();
 app.UseAuthorization();
    
 app.UseEndpoints(endpoints =>
 {
     endpoints.MapControllerRoute(
     ...
     endpoints.MapHub<NewsHub>("/newshub");
 });



repro and simplified question is here: https://docs.microsoft.com/en-us/answers/questions/497227/signalr-authorization-not-working-out-of-the-box-i.html






dotnet-aspnet-core-generaldotnet-aspnet-general
· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi @Maxima-5691,
Hello, is your problem solved? If it is solved, I suggest you post the solution to this post to help other people who have encountered similar problems. If it is not solved, what problems are you encountering now?
https://docs.microsoft.com/en-us/answers/questions/497227/signalr-authorization-not-working-out-of-the-box-i.html

0 Votes 0 ·
Maxima-5691 avatar image
0 Votes"
Maxima-5691 answered Maxima-5691 edited

I found 3 solutions to this problem. First was a workaround (using a controller authentication to make sure the client has rights to use hub):
https://stackoverflow.com/a/68632110/347484

but after cleaning my glasses and the head I found that the solution was always before me (the template created auth.service.ts which has getAccessToken already): https://stackoverflow.com/a/68682651/347484

and of course there is another way:
https://docs.microsoft.com/en-us/answers/questions/497227/signalr-authorization-not-working-out-of-the-box-i.html

accessTokenFactory: () => JSON.parse(sessionStorage.getItem("oidc.user:https://localhost:44388:Source")).access_token})

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Bruce-SqlWork avatar image
0 Votes"
Bruce-SqlWork answered Maxima-5691 edited

you are using cookie authentication for the website. this works for javascript ajax calls, because the cookie is part of the http protocol. You can also configure signal/r to use cookie authentication. see:

https://docs.microsoft.com/en-us/aspnet/core/signalr/authn-and-authz?view=aspnetcore-5.0


· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Thank you Bruce. I read that article 15 times in past 2 days. I just dont understand what has to be done (and also in first place why is it not working out of the box).

Now - "you are using cookie authentication" - am I? I dont see it. The fiddler says - there are both a cookie and bearer auth header (see the picture - it is from a sample app which has almost zero logic - microsoft weather forecast template. i just added signalr to it : https://docs.microsoft.com/en-us/answers/questions/497227/signalr-authorization-not-working-out-of-the-box-i.html

there is also this in the Startup: AddIdentityServerJwt

119588-image.png



but lets assume you are right. then reading second paragraph (Cookie authentication):

In a browser-based app, cookie authentication allows your existing user credentials to automatically flow to SignalR connections. When using the browser client, no additional configuration is needed. If the user is logged in to your app, the SignalR connection automatically inherits this authentication.

if you know the answer please tell. because i am at sea here..

0 Votes 0 ·
image.png (123.4 KiB)

I think I proved that its not cookie I use. When I tried to specify Cookie as Authorization scheme on the hub class I got this error:

System.InvalidOperationException: No authentication handler is registered for the scheme 'Cookies'.
The registered schemes are: Identity.Application, Identity.External, Identity.TwoFactorRememberMe, Identity.TwoFactorUserId, idsrv, idsrv.external, IdentityServerJwt, IdentityServerJwtBearer.

0 Votes 0 ·