asp.net SignalR集线器上下文获取返回空值

ca1c2owp  于 2023-01-18  发布在  .NET
关注(0)|答案(1)|浏览(260)

我正在使用SignalR和angular客户端在特定客户端之间建立一个聊天。我有一个用于JWT令牌登录的微服务,另一个用于SignalR的微服务是授权的。到目前为止,我的应用程序运行良好,我正在设法登录并使用我的令牌连接到SignalR。我正在从我的客户端发送我想发送消息的用户名,我也想发给我自己。问题是当我使用-

Context.User.Identity.Name

我总是得到null,尽管我对我的令牌有这样的声明-

new Claim(ClaimTypes.NameIdentifier, user.UserName)

我在干什么?
用户中心:

[Authorize]
public class UserHub : Hub
{
    private readonly IHubContext<UserHub> _hubContext;

    public UserHub(IHubContext<UserHub> hubContext)
    {
        _hubContext = hubContext;
    }
 public void  SendMessageToUser(string name, string message)
    {
        var mySelf =Context.User.Identity.Name;     // always null
        _hubContext.Clients.Users(Context.User.Identity.Name, name).SendAsync("GetMessage", message, name).Wait();
    }

令牌服务(单独的微服务)-

public string? GetToken(string userName, string password)
    {
        var user = _userRepository.GetByUserName(userName);
        if (user != null && user.Password == password)
        {
            var claims = new[]
           {      
                new Claim(JwtRegisteredClaimNames.Sub, _configuration["Jwt:Subject"]),
                new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
                new Claim(JwtRegisteredClaimNames.Iat, DateTime.UtcNow.ToString()),
                new Claim("userId", user.Id.ToString()),
                new Claim(ClaimTypes.NameIdentifier, user.UserName),
        };
            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:Key"]));
            var signIn = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
            var token = new JwtSecurityToken(
                _configuration["Jwt:Issuer"],
                _configuration["Jwt:Audience"],
                claims,
                expires: DateTime.UtcNow.AddMinutes(10),
                signingCredentials: signIn);
     
            return new JwtSecurityTokenHandler().WriteToken(token);
        }
        else
            return null;
    }

令牌(部件)程序-

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
{
    options.RequireHttpsMetadata = false;
    options.SaveToken = true;
    options.TokenValidationParameters = new TokenValidationParameters()
    {
        ValidateIssuer = false,
        ValidateAudience = false,
        ValidateIssuerSigningKey=true,
        ValidAudience = builder.Configuration["Jwt:Audience"],
        ValidIssuer = builder.Configuration["Jwt:Issuer"],
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]))
    };

SignalR程序(部件)-

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
{
    options.TokenValidationParameters = new TokenValidationParameters()
    {
        ValidateIssuer = false,
        ValidateAudience = false,
        ValidateIssuerSigningKey=true,
        ValidAudience = builder.Configuration["Jwt:Audience"],
        ValidIssuer = builder.Configuration["Jwt:Issuer"],
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]))
    };
    options.Events = new JwtBearerEvents
    {
        OnMessageReceived = context =>
        {
            var accessToken = context.Request.Query["access_token"];
            var path = context.HttpContext.Request.Path;
            if (!string.IsNullOrEmpty(accessToken) && (path.StartsWithSegments("/user")))
            {
                context.Token = accessToken;
            }
            return Task.CompletedTask;
        }
    };
});
yquaqz18

yquaqz181#

使用Context.User.Identity.FindFirst(ClaimTypes.NameIdentifier)?.ValueContext.UserIdentifierIdentity.Name用于ClaimTypes.Name
此外,_hubContext.Clients.Users()默认使用NameIdentifier,因此即使您有该声明,Name也不会工作。
这是可自定义的,并在www.example.com上的文档中进行了说明https://learn.microsoft.com/aspnet/core/signalr/authn-and-authz?view=aspnetcore-7.0#use-claims-to-customize-identity-handling

相关问题