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

SignalR Angular客户端连接.NET 8 Azure服务遇查询字符串过长404.15错误

SignalR查询字符串过长(404.15)问题解决方案

你不是唯一遇到这个问题的开发者

很多使用SignalR结合长JWT Bearer令牌的开发者都碰到过这类问题——浏览器(尤其是Edge/Chrome)和IIS对URL/查询字符串的长度限制,加上默认情况下SignalR浏览器客户端会把令牌放在查询字符串中传递,很容易触发404.15错误。

你当前操作的潜在问题

  1. 依赖查询字符串传递令牌:不仅会触发长度限制问题,还存在安全风险——令牌会被记录在服务器日志、浏览器历史记录和网络请求日志中,增加泄露风险。
  2. 未利用SignalR的Negotiate机制传递令牌:默认的查询串传令牌是 fallback 方案,其实可以通过Negotiate请求的Header传递令牌,从根源上规避长度限制。

通用简便解决方案

1. Angular(JS客户端)修改方案

放弃查询串传令牌,改为在Negotiate请求的Authorization Header中传递令牌,SignalR会基于Negotiate返回的连接ID建立后续WebSockets连接,无需再在URL中携带令牌:

import { HubConnectionBuilder, HttpTransportType } from '@microsoft/signalr';

// 替换为你的令牌和Hub地址
const authToken = 'your-msal-acquired-token';
const hubUrl = '/your-hub-endpoint';

const connection = new HubConnectionBuilder()
  .withUrl(hubUrl, {
    transport: HttpTransportType.WebSockets,
    // 配置HttpClient在Negotiate请求中添加Authorization Header
    configureHttpClient: (httpClient) => {
      httpClient.defaults.headers.common['Authorization'] = `Bearer ${authToken}`;
    },
    skipNegotiation: false, // 必须开启Negotiate流程,才能传递Header
  })
  .build();

2. Blazor客户端修改方案

通过自定义HttpMessageHandler在Negotiate请求中添加Authorization Header,避免令牌出现在查询字符串中:

using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR.Client;

var hubUrl = "your-hub-url";
var token = "your-acquired-token";

var hubConnection = new HubConnectionBuilder()
  .WithUrl(hubUrl, options =>
  {
    options.CloseTimeout = TimeSpan.FromSeconds(120);
    options.Transports = HttpTransportType.WebSockets;
    // 配置消息处理器添加Authorization Header
    options.HttpMessageHandlerFactory = handler => new AuthHeaderHandler(handler, token);
    // 关闭默认的查询串令牌传递
    options.AccessTokenProvider = null;
  })
  .Build();

// 自定义DelegatingHandler用于添加Authorization Header
public class AuthHeaderHandler : DelegatingHandler
{
  private readonly string _bearerToken;

  public AuthHeaderHandler(HttpMessageHandler innerHandler, string bearerToken) 
    : base(innerHandler)
  {
    _bearerToken = bearerToken;
  }

  protected override Task<HttpResponseMessage> SendAsync(
    HttpRequestMessage request, 
    CancellationToken cancellationToken)
  {
    // 仅在Negotiate请求中添加Header
    if (request.RequestUri?.PathAndQuery.Contains("/negotiate") == true)
    {
      request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _bearerToken);
    }
    return base.SendAsync(request, cancellationToken);
  }
}

如果是Blazor WebAssembly应用,还可以直接利用AuthorizationMessageHandler简化配置:

using Microsoft.AspNetCore.Components.WebAssembly.Authentication;

var handler = new AuthorizationMessageHandler();
handler.ConfigureHandler(
  authorizedUrls: new[] { hubUrl },
  scopes: new[] { "your-api-required-scope" });

var hubConnection = new HubConnectionBuilder()
  .WithUrl(hubUrl, options =>
  {
    options.CloseTimeout = TimeSpan.FromSeconds(120);
    options.Transports = HttpTransportType.WebSockets;
    options.HttpMessageHandlerFactory = _ => handler;
  })
  .Build();

3. 服务器端配套配置

保留你之前在web.config中设置的请求长度限制,以防SignalR fallback到ServerSentEvents或LongPolling等其他传输方式时触发长度问题:

<security>
    <requestFiltering>
        <requestLimits maxUrl="4096" maxQueryString="4096" />
    </requestFiltering>
</security>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 07:13:17