首页 > 解决方案 > 在 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;
        }
    }
}

标签: asp.net-core.net-coremiddlewaresignalr-hub

解决方案


如果您想检查 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;
                    },

推荐阅读