我正在使用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;
}
};
});
1条答案
按热度按时间yquaqz181#
使用
Context.User.Identity.FindFirst(ClaimTypes.NameIdentifier)?.Value
或Context.UserIdentifier
。Identity.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