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

SignalR集成AzureAD认证后WebSocket降级为长轮询问题求助

SignalR + Azure AD 认证降级排查思路

1. 先解决OnMessageReceived未触发的问题

  • 检查认证中间件顺序:必须保证app.UseAuthentication()放在app.UseRouting()和app.UseEndpoints()之前,否则SignalR请求到达Hub时认证逻辑还未执行,自然触发不了该事件。
  • 验证路径匹配逻辑:在OnMessageReceived里添加日志输出context.HttpContext.Request.Path和SomeHub.Path的实际值,确认StartsWithSegments是否真的匹配上了Hub的路由路径。
  • 核对认证Scheme一致性:Hub的[Authorize]指定了JwtBearerDefaults.AuthenticationScheme,确保配置里的JWT Scheme(代码中为"Bearer")和这个完全一致,没有其他认证Scheme(比如Cookie)优先拦截请求。

2. 修正客户端SignalR配置参数

你当前的withUrl参数顺序错误,第二个参数应该是一个配置对象,而非拆分的布尔值和枚举,这会导致令牌传递配置失效:

let optimizerConnection = new HubConnectionBuilder()
    .withUrl("/hubpath", { 
        accessTokenFactory: () => getRawJwtToken(),
        skipNegotiation: false,
        transport: HttpTransportType.WebSockets
    })
    .withAutomaticReconnect()
    .configureLogging(LogLevel.Trace)
    .build()

修改后用浏览器F12查看:

  • 协商请求(/hubpath/negotiate)的查询参数中是否携带access_token
  • WebSocket连接请求的URL里是否包含access_token参数(WebSocket不支持自定义请求头,SignalR默认用查询字符串传递令牌)

3. 调整服务端JWT事件配置

不要直接通过new JwtBearerEvents()覆盖默认事件,这会丢失Microsoft Identity Web Api的内置逻辑,应采用追加事件的方式:

private static void ConfigureJwtBearerOptions(JwtBearerOptions options)
{
    // 仅追加OnMessageReceived,保留原有默认事件
    options.Events.OnMessageReceived = context =>
    {
        var accessToken = context.Request.Query["access_token"];
        var path = context.HttpContext.Request.Path;
        if (!string.IsNullOrEmpty(accessToken) && path.StartsWithSegments("/hubpath"))
        {
            context.Token = accessToken;
        }
        return Task.CompletedTask;
    };

    // 其他事件单独赋值,不替换整个Events对象
    options.Events.OnChallenge = OnChallenge;
    options.Events.OnTokenValidated = OnTokenValidated;
    options.Events.OnAuthenticationFailed = OnAuthenticationFailed;
    options.Events.OnForbidden = OnForbidden;
}

4. 排查连接降级的具体原因

  • 开启SignalR诊断日志,在appsettings.json中添加:
    {
      "Logging": {
        "LogLevel": {
          "Microsoft.AspNetCore.SignalR": "Debug",
          "Microsoft.AspNetCore.Http.Connections": "Debug"
        }
      }
    }
    
    日志会明确显示WebSocket被降级的原因,比如认证失败、协议不支持等。
  • 检查协商请求状态:如果/hubpath/negotiate返回401,SignalR会直接降级传输方式。确保协商请求能通过认证,它是HTTP请求,可以携带Authorization头。
  • 验证令牌权限:用JWT解析工具检查令牌内是否包含Optimizer角色,角色名称大小写要和[Authorize]中的完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 21:30:21