You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET SignalR使用JWT授权时出现401 Unauthorized错误问题求助

问题根因与解决方案

核心问题1:SignalR查询参数中Token的参数名错误

WebSocket协议不支持自定义请求头,所以SignalR客户端的accessTokenFactory返回的token会默认放到URL查询参数中,参数名为access_token,而你当前服务端OnMessageReceived事件中读取的是查询参数的authorization字段,自然取不到token导致401。

核心问题2:请求头中的Authorization带Bearer前缀未处理

如果你从Header读取Authorization值,默认格式是Bearer <token>,直接赋值给ctx.Token会把Bearer 前缀也带入验证逻辑,导致token格式错误。

其他兼容/配置问题

  • 客户端@microsoft/signalr@5.x和服务端Microsoft.AspNetCore.SignalR@1.x跨大版本存在兼容性风险,建议服务端升级到对应.NET Core 3.1+版本,或者客户端降级到1.x版本对齐。
  • CORS配置中存在拼写错误:WithOrigins("http://locahost:4000")里的locahost少了字母l,正确应为localhost。

修复步骤

  1. 调整服务端OnMessageReceived事件中的token读取逻辑,示例修改如下:
OnMessageReceived = ctx =>
{
    Log.Logger.Information("Authentication - Message received.");
    var path = ctx.HttpContext.Request.Path;
    if (!path.StartsWithSegments("/apphub", StringComparison.OrdinalIgnoreCase))
    {
        return Task.CompletedTask;
    }

    // 优先读取SignalR默认的access_token查询参数
    if (ctx.Request.Query.TryGetValue("access_token", out var queryToken))
    {
        ctx.Token = queryToken;
        return Task.CompletedTask;
    }

    // 读取Header的话需要移除Bearer前缀
    if (ctx.Request.Headers.TryGetValue("Authorization", out var headerToken))
    {
        var token = headerToken.ToString().Replace("Bearer ", string.Empty);
        if (!string.IsNullOrEmpty(token))
        {
            ctx.Token = token;
        }
    }
    return Task.CompletedTask;
}
  1. 修正CORS配置中的域名拼写错误,本地调试可以直接用AllowAnyOrigin配合AllowCredentials即可。
  2. 对齐客户端和服务端的SignalR主版本,避免跨版本兼容问题。
  3. 确认服务端中间件顺序正确:必须先调用UseAuthentication,再调用UseAuthorization,最后调用UseEndpoints/UseSignalR。

内容的提问来源于stack exchange,提问作者user1563232

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 09:24:05