我想了解为什么
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 文档并用谷歌搜索了很多。
我有同样的问题。问题是当您将请求挂接到您的中心时,没有 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>();