SignalR Hub中无法访问Context/User,JWT认证异常求助
问题排查与解决方案
1. 前后端Hub路径不匹配
前端连接的路径是api/TicketSocket,但后端MapHub配置的是/TicketSocket,且OnMessageReceived事件中判断路径是否以/TicketSocket开头——这导致前端请求的/api/TicketSocket不满足条件,JWT令牌未被赋值给context.Token,认证中间件无法获取令牌验证,最终Context.User为空。
修复方案:
统一前后端路径,二选一即可:
- 前端修改连接路径:
this.connection = new HubConnectionBuilder() .withUrl(`/TicketSocket`, { accessTokenFactory: () => this.$auth.strategy.token.get(), }) .withAutomaticReconnect() .build() - 后端同步路径配置:
// 更新OnMessageReceived的路径判断 if (!string.IsNullOrEmpty(accessToken) && path.StartsWithSegments("/api/TicketSocket")) { context.Token = accessToken; } // 更新MapHub路径 endpoints.MapHub<TicketHub>("/api/TicketSocket");
2. 确认授权策略IsAuthenticated的定义
你在[Authorize]中指定了Policy = "IsAuthenticated",但代码未展示该策略配置。若未定义此策略,授权会失败,导致Context.User无法被正确填充。
修复方案:
在Program.cs中添加策略定义:
builder.Services.AddAuthorization(options => { options.AddPolicy("IsAuthenticated", policy => { policy.RequireAuthenticatedUser(); }); });
3. 调整中间件顺序
当前UseWebSockets放在UseAuthentication之前,不符合SignalR推荐的中间件顺序,可能影响认证流程。正确顺序应为:
var app = builder.Build(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseWebSockets(); // 移至授权之后、端点配置之前 app.UseEndpoints(endpoints => { endpoints.MapControllers(); endpoints.MapHub<TicketHub>("/TicketSocket"); });
4. 将[Authorize]应用到Hub类级别
SignalR授权建议直接作用于Hub类,确保所有Hub方法(包括OnConnectedAsync)都经过认证验证:
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme, Policy = "IsAuthenticated")] public class TicketHub : Hub { private readonly ITicketsRepository _ticketRepository; public TicketHub(ITicketsRepository ticketRepository) { _ticketRepository = ticketRepository; } public override async Task OnConnectedAsync() { var isAuthenticated = Context.User.Identity.IsAuthenticated; // 后续业务逻辑 } }
验证步骤
- 修复路径匹配问题后重启服务
- 前端重新连接Hub,检查
Context.User是否被正确填充 - 若仍有问题,可在
OnMessageReceived事件中添加日志,确认accessToken和请求路径是否符合预期
内容的提问来源于stack exchange,提问作者RETOVSKEJ
相关产品推荐
相关产品推荐

