我正在使用 .net 6.0 中的 SignalR 从事通知服务工作。 我需要通过查询通过令牌获取数据用户,但是,它像空一样到达。 我找不到更多信息,我不知道还能做什么。
我的程序.cs:
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(o =>
{
o.TokenValidationParameters = new TokenValidationParameters
{
//ValidIssuer = builder.Configuration["Jwt:Issuer"],
// ValidAudience = builder.Configuration["Jwt:Audience"],
IssuerSigningKey = new SymmetricSecurityKey
(Encoding.UTF8.GetBytes(builder.Configuration["secreatKey"])),
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = false,
ValidateIssuerSigningKey = true
};
o.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
var accessToken = context.Request.Query["access_token"];
if (string.IsNullOrEmpty(accessToken) == false)
{
context.Token = accessToken;
}
return Task.CompletedTask;
}
};
});
我的中心:
public class NotificationHub : Hub<INotificationHub>
{
//Crea la Conexion
private readonly NotificationMemoryStorage _notificationStorage;
public NotificationHub(NotificationMemoryStorage notificationMemoryStorage)
{
_notificationStorage = notificationMemoryStorage;
}
public override async Task OnConnectedAsync()
{
var userId = GetUserIdFromToken();
if(!string.IsNullOrEmpty(userId))
{
var notifications = _notificationStorage.GetNotifications(userId);
foreach (var notification in notifications)
{
await Clients.User(userId).SendNotification(notification);
}
_notificationStorage.ClearNotifications(userId);
var response = new ServerResponse
{
status = "Acepted",
};
await Clients.Client(Context.ConnectionId).ConnectionResponse(response);
}
await base.OnConnectedAsync();
}
public override async Task OnDisconnectedAsync(Exception? exception)
{
await base.OnDisconnectedAsync(exception);
}
public async Task MessageCheck(NotificationRequestModel request)
{
//meter validaciones
switch (request.Target.Device)
{
case "Admin":
if (request.Target.User.Contains("*"))
{
SendNotificationToAllUsers(request.Notification);
}
else
{
//SendNotificationToSpecificUser(request, request.Target.User);
}
break;
}
}
//Desconecta del Servidor
public async Task SendNotificationToAllUsers(NotificationModel message)
{
await Clients.All.SendNotificationToAllUsers(message);
}
private string GetUserIdFromToken()
{
var token = Context.GetHttpContext();
var jwt = token.Request.Headers["access_token"];
var identity = (ClaimsIdentity)Context.User.Identity;
var userIdClaim = identity.FindFirst(ClaimTypes.NameIdentifier);
return userIdClaim?.Value;
}
//public async Task SendNotificationToSpecificUser(NotificationRequestModel message, List<string> target)
//{
// foreach (var item in target)
// {
// //if (ConnectedUsers.TryGetValue(item, out var user))
// //{
// await Clients.Client(user.ConnectionId).SendNotification(message);
// //}
// }
//}
}
这里数据到达时为空:
private string GetUserIdFromToken()`enter code here`
{
var token = Context.GetHttpContext();
var jwt = token.Request.Headers["access_token"];
var identity = (ClaimsIdentity)Context.User.Identity;
var userIdClaim = identity.FindFirst(ClaimTypes.NameIdentifier);
return userIdClaim?.Value;
}
我认识到我不知道自己在做什么。
一路上遇到一些小问题,试试这样吧
第1步:
从查询字符串请求中删除承载前缀
?access_token=bearerXXXX
--> ?access_token=XXXX
第2步:
从查询中读取令牌,并将令牌和带有空格的承载前缀应用于 OnMessageReceived 事件中的授权标头
OnMessageReceived = context =>
{
var accessToken = context.Request.Query["access_token"];
if (!string.IsNullOrEmpty(accessToken))
{
context.Request.Headers.Add("Authorization", $"Bearer {token}");
}
return Task.CompletedTask;
}
第三步:
通过将授权属性添加到类中来在集线器上强制授权
[Authorize]
public class NotificationHub : Hub<INotificationHub>