6

I would like to understand why Context.User.Identity.Name is null and why Context.User.Identity.IsAuthenticated is false inside a signalr Hub in the onConnectedAsync method? Msdn says:

"SignalR can be used with ASP.NET Core authentication to associate a user with each connection...

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

Project code available here :

https://github.com/nl20121974/CC

Précision : in this case, user was previously authenticated with the standard authentication form against membership individual accounts (database username + password) from the blazor app. I started with the Microsoft blazor chat sample. This one :

https://learn.microsoft.com/en-us/azure/azure-signalr/signalr-tutorial-build-blazor-server-chat-app

The user logs in first from the authentication form with credentials (username + password) from database (.net membership) and goes to the chat page where the user name is automatically sent to chat hub when the "Chat" button is clicked.

enter image description here

enter image description here

enter image description here

enter image description here

I would like to fill a connected users list from signalr hub directly

I searched on Msdn blazor and signalr documentation and Googled a lot.

9
  • Because the web app allows anonymous authentication and the users aren't authenticated. There are no connected users to list, just nameless connections Commented Apr 4, 2023 at 7:03
  • I edited my post : in this case, user was previously authenticated with the standard authenticatiion form from the blazor app. I started with the Microsoft blazor chat sample. Commented Apr 4, 2023 at 7:13
  • We can't guess how the web app and specifically authentication was configured. Not even what sample was used. The Azure SignalR sample demonstrates the Azure SignalR service and doedn't use authentication either. The username is entered manually by the user Commented Apr 4, 2023 at 7:22
  • The SignalR with Blazor sample doesn't use authentication either. Once again the username is entered manually Commented Apr 4, 2023 at 7:25
  • I update my post : This one : learn.microsoft.com/en-us/azure/azure-signalr/… The user logs in first from the authenticatiion form and goes to the chat page where the user name is automatically sent to chat hub when the "Chat" button is clicked. Commented Apr 4, 2023 at 7:33

2 Answers 2

1

I had the same issue. The problem is when you hook the request in your hub, there is no JWT token. (If you use JWT token also)

(I'm in .NET 6)

So you need to create a PostConfigureOptions class:

public class ConfigureJwtBearerOptions : IPostConfigureOptions<JwtBearerOptions>
{
    public void PostConfigure(string name, JwtBearerOptions options)
    {
        var originalOnMessageReceived = options.Events.OnMessageReceived;
        options.Events.OnMessageReceived = async context =>
        {
            await originalOnMessageReceived(context);

            if (string.IsNullOrEmpty(context.Token))
            {
                var accessToken = context.Request.Query["access_token"];
                var path = context.HttpContext.Request.Path;

                if (!string.IsNullOrEmpty(accessToken) &&
                    path.StartsWithSegments("/hub"))
                {
                    context.Token = accessToken;
                }
            }
        };
    }
}

in you Program.cs :

services.TryAddEnumerable(ServiceDescriptor.Singleton<IPostConfigureOptions<JwtBearerOptions>, ConfigureJwtBearerOptions>());

Everything is detailled here : SignalR authentication & authorization

I also created a AppClaimsPrincipalFactory. But I'm not sure you would need this:

public class AppClaimsPrincipalFactory : UserClaimsPrincipalFactory<ApplicationUser, IdentityRole>
{
    public AppClaimsPrincipalFactory(UserManager<ApplicationUser> userManager, RoleManager<IdentityRole> roleManager, IOptions<IdentityOptions> optionsAccessor)
        : base(userManager, roleManager, optionsAccessor)
    { 

    }

    public async override Task<ClaimsPrincipal> CreateAsync(ApplicationUser user)
    {
        var principal = await base.CreateAsync(user);
        if (!string.IsNullOrWhiteSpace(user.FirstName))
            ((ClaimsIdentity)principal.Identity).AddClaims(new[] {new Claim(ClaimTypes.GivenName, user.FirstName)});
            
        if (!string.IsNullOrWhiteSpace(user.LastName))
            ((ClaimsIdentity)principal.Identity).AddClaims(new[] {new Claim(ClaimTypes.Surname, user.LastName)});

        if (!string.IsNullOrWhiteSpace(user.Email))
            ((ClaimsIdentity)principal.Identity).AddClaims(new[] { new Claim(ClaimTypes.Email, user.Email) });

        return principal;
    }
}



services.AddScoped<IUserClaimsPrincipalFactory<ApplicationUser>, AppClaimsPrincipalFactory>();
Sign up to request clarification or add additional context in comments.

6 Comments

Hi bisjob, i updated my post, i am not using token but individual account from .net membeeship
Can you show us the ConfigureServices() method in your Startup.cs ?
Will dit it this evening, i updated my post this morning. The project code is here : github.com/nl20121974/CC
It seems you need to add your authCookie in the hubConnection : _hubConnection = new HubConnectionBuilder().WithUrl(_hubUrl, o => o.Cookies = authCookie).Build();. On Blazor wasm, I need provide a TokenProvider using Microsoft.AspNetCore.Components.WebAssembly.Authentication.IAccessTokenProvider (Because I have JWT auth)
No it's written in msdn for my case : SignalR can be used with ASP.NET Core authentication to associate a user with each connection. In a browser-based app, cookie authentication allows existing user credentials to automatically flow to SignalR connections. When using the browser client, no extra configuration is needed. If the user is logged in to an app, the SignalR connection automatically inherits this authentication.
|
-1

Get username in blazor .Net6 .Net8

in page:

    @using BlazorApp1.Data
    @using Microsoft.EntityFrameworkCore
    @inject AuthenticationStateProvider GetAuthenticationStateAsync

@email


@code{
string email;
    protected override async Task OnInitializedAsync()
    {
        var authstate = await GetAuthenticationStateAsync.GetAuthenticationStateAsync();
        var user = authstate.User;
        var name = user.Identity.Name;
        email = name;
    }
}

2 Comments

Not from client but from the signalr hub, to full a list of connected users in the chat hub
The question is about getting the username from HttpContext in a SignalR Hub, Not about getting the username from AuthenticationStateProvider in a Blazor component.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.