.NET Core+Angular部署Azure后SignalR WebSocket握手返回302错误如何处理
解决方案
1. 开启Azure App Service的WebSocket支持
Azure App Service默认关闭WebSocket功能,部署后需手动开启:
- 进入对应App Service的Azure管理页面,依次打开「设置」→「配置」→「常规设置」
- 找到「Web 套接字」选项,切换为开启状态,保存配置后重启应用服务
2. 禁止JWT校验失败时返回重定向响应
报错的302状态码本质是JWT校验失败后,Azure AD身份验证中间件对请求返回了登录页重定向,而非预期的401状态码,导致WebSocket握手失败。SignalR会自动降级到长轮询/服务器发送事件传输,所以功能仍正常,仅控制台报错。
在你现有的AddJwtBearer配置块中新增OnChallenge事件处理逻辑即可解决:
services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }).AddJwtBearer(options => { options.Authority = "https://sts.windows.net/tenat/v2.0"; options.Audience = Configuration.GetSection("AzureAd").GetSection("Audience").Value; options.TokenValidationParameters.ValidateLifetime = true; options.Events = new JwtBearerEvents { OnMessageReceived = context => { var accessToken = context.Request.Query["access_token"]; var path = context.HttpContext.Request.Path; if (!string.IsNullOrEmpty(accessToken) && (path.StartsWithSegments("/notifications"))) { context.Token = accessToken; } return Task.CompletedTask; }, // 新增以下逻辑 OnChallenge = context => { // 跳过默认重定向逻辑,直接返回401 context.HandleResponse(); context.Response.StatusCode = StatusCodes.Status401Unauthorized; return Task.CompletedTask; } }; });
3. 可选:显式配置SignalR传输策略
如果希望优先使用WebSocket获得更好的性能,可以在Angular端构建Hub连接时显式指定传输顺序:
import { HttpTransportType } from '@microsoft/signalr'; private createConnection() { this.hubConnection = new signalR.HubConnectionBuilder() .withUrl(`${this.libraryConfig.api.notification.baseUrl}/notifications`, { accessTokenFactory: () => this.access_token, transport: HttpTransportType.WebSockets | HttpTransportType.ServerSentEvents | HttpTransportType.LongPolling }) .build(); }
4. 额外检查项
如果你的Azure App Service开启了内置的「身份验证/授权」(易鉴权)功能,需确认:
- 允许未认证请求到达应用,由应用自身处理JWT校验,避免App Service层面拦截请求返回302重定向
- 确认前端传入的access_token的签发方、受众与后端Azure AD配置完全匹配,避免令牌校验失败
内容的提问来源于stack exchange,提问作者Aracelis S
相关产品推荐
相关产品推荐

