.NET 9 Aspire BFF:如何让反向代理捕获SignalR连接并添加令牌
解决方案:让反向代理捕获SignalR连接请求并添加令牌
核心问题定位
你的SignalR客户端直接硬编码了目标API的地址(https://localhost:7027/messageHub),导致请求没有经过Blazor应用的反向代理,直接发送到了目标API,所以代理根本捕获不到这个请求。另外,SignalR的WebSocket传输需要特殊配置才能被反向代理正确处理。
步骤1:修正SignalR客户端连接地址
把客户端的连接地址改成相对路径,让请求先经过Blazor服务器的反向代理:
var url = "/messageHub"; // 改为相对路径,走反向代理 HubConnection = new HubConnectionBuilder() .WithUrl(Navigation.ToAbsoluteUri(url), options => { options.HttpMessageHandlerFactory = innerHandler => new KoHttpMessageHandler { InnerHandler = innerHandler }; }).Build();
步骤2:配置反向代理支持WebSocket
SignalR默认优先使用WebSocket传输,需要在反向代理中启用WebSocket支持,确保握手请求能被正确转发:
// 先添加WebSocket中间件,必须放在MapForwarder之前 app.UseWebSockets(); app.MapForwarder("/{**catch-all}", "https://localhost:7027", transformBuilder => { transformBuilder.AddRequestTransform(async transformContext => { // OPTIONS预检请求不需要添加令牌,避免被CORS策略拒绝 if (transformContext.HttpContext.Request.Method == HttpMethod.Options.Method) return; var tokenAcquisition = transformContext.HttpContext.RequestServices.GetRequiredService<ITokenAcquisition>(); var configuration = transformContext.HttpContext.RequestServices.GetRequiredService<IConfiguration>(); var accessToken = await tokenAcquisition.GetAccessTokenForUserAsync([$"{configuration["DownstreamApis:MyApi-API:AppIdUri"]}/{configuration["DownstreamApis:MyApi:Scope"]}"]); transformContext.ProxyRequest.Headers.Authorization = new("Bearer", accessToken); }); }) // 启用WebSocket转发支持 .WithMetadata(new WebSocketProxyMetadata());
关键说明
- 相对路径的作用:将客户端连接地址改为相对路径后,所有SignalR请求(包括协商请求、WebSocket握手请求)都会先发送到Blazor应用服务器,再由反向代理转发到目标API,这样代理就能捕获请求并添加令牌。
- WebSocket配置:
UseWebSockets()中间件和WebSocketProxyMetadata是确保反向代理能正确处理WebSocket升级请求的必要配置,否则SignalR无法建立WebSocket连接。 - 跳过OPTIONS请求的令牌添加:浏览器发送的CORS预检请求(OPTIONS)不应该携带Authorization头,跳过这类请求的令牌添加可以避免目标API的CORS策略拒绝请求。
内容的提问来源于stack exchange,提问作者GH DevOps
相关产品推荐
相关产品推荐

