asp.net-core - 在 SignalR 中间件中添加到上下文项
问题描述
所以我想设置一个适用于 SignalR 集线器和控制器的用户中间件。它适用于正常请求,但使用信号器时它会被调用但不会添加到上下文中。甚至可能吗?如果是这样,我该怎么做?
namespace PortalCore.Middleware
{
public class JwtMiddleware
{
private readonly RequestDelegate _next;
public JwtMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context, AuthService authService)
{
var token = context.Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last();
if (token != null)
{
AttachUserToContext(context, authService, token);
}
await _next(context);
}
private async void AttachUserToContext(HttpContext context, AuthService authService, string token)
{
User user = null;
var tokenHandler = new JwtSecurityTokenHandler();
try
{
tokenHandler.ValidateToken(token, new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey =
new SymmetricSecurityKey(System.Text.Encoding.UTF8.GetBytes(authService.SecretKey)),
ValidateIssuer = false,
ValidateAudience = false,
ClockSkew = TimeSpan.Zero
}, out SecurityToken validatedToken);
var jwtToken = (JwtSecurityToken)validatedToken;
user = await authService.GetUserByUid(jwtToken.Claims.FirstOrDefault()?.Value);
}
catch (Exception e)
{
}
context.Items["User"] = user;
}
}
}
解决方案
如果您想检查 signalR 集线器的身份验证,那么您可以使用查询字符串来执行此操作。您可以使用 signalR 客户端 url 发送令牌。从查询字符串中获取令牌并设置为上下文之后。
集线器代码:
[Authorize]
public class ChatHub : Hub
您可以在 Context 中添加令牌:
OnMessageReceived = context =>
{
var accessToken = context.Request.Query["access_token"];
var path = context.HttpContext.Request.Path;
if (!string.IsNullOrWhiteSpace(accessToken) &&
(path.StartsWithSegments("/api/hubs/chatHub")))
{
context.Token = accessToken;
}
return Task.CompletedTask;
},
推荐阅读
- c# - 无法将多个生成的 Html.DropDownListFor 绑定到 ViewModel
- xquery - 如何通过 xquery 在 Marklogic 中设置集群?
- reactjs - 真实项目的纯 mobx(无 MST)存储模型
- docker - Docker - 运行容器时清理文件内容
- javascript - 如何在javascript中将时间转换为用户本地时区
- amazon-web-services - 如何在 CloudFormation 中指定 AMI?
- javascript - 我应该使用什么来代替 document.getElementById 才能使它起作用
- latex - 如何在文本中间创建一个数字以便引用它们?
- plsql - 我可以从存储过程中调用 SQL Developer PL/SQL 格式化吗
- javascript - 如何使用 testcafe 拦截和模拟 websocket 请求