从 blazor 服务器应用程序 (.NET 7) 中的信号中心获取 Context.User.Identity

问题描述 投票:0回答:1

我想了解为什么

Context.User.Identity.Name
null
以及为什么
Context.User.Identity.IsAuthenticated
false
onConnectedAsync
方法中的信号器中心内?

此处提供代码示例:

https://github.com/nl20121974/CC

Précision:在这种情况下,用户先前已通过 blazor 应用程序中的会员个人帐户(数据库用户名 + 密码)的标准身份验证表单进行了身份验证。我从 Microsoft Blazor 聊天示例开始。这个:

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

用户首先使用数据库(.net 会员资格)中的凭据(用户名 + 密码)从身份验证表单登录,然后转到聊天页面,单击“聊天”按钮时,用户名会自动发送到聊天中心。

我想直接从 signalr hub 填写连接的用户列表

我搜索了 Msdn blazor 和 signalr 文档并用谷歌搜索了很多。

blazor signalr identity .net-7.0 hub
1个回答
0
投票

我有同样的问题。问题是当您将请求挂接到您的中心时,没有 JWT 令牌。 (如果你也使用 JWT 令牌)

(我在 .NET 6 中)

所以需要创建一个PostConfigureOptions类:

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;
                }
            }
        };
    }
}

在你的 Program.cs 中:

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

一切都在这里详细说明:SignalR 身份验证和授权

我还创建了一个 AppClaimsPrincipalFactory。但我不确定你是否需要这个:

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>();
© www.soinside.com 2019 - 2024. All rights reserved.