如何在Asp.Net Core SignalR Hub中获取Bearer Token原始字符串?
在ASP.NET Core SignalR Hub中获取Bearer Token原始字符串的解决方案
我刚好处理过类似的场景,SignalR的长连接特性确实会让Per-request模式的Token获取方式失效,不过我们可以利用SignalR连接初始化时的HTTP请求上下文来提取Token,并将其存储在连接的上下文里供后续使用。下面是具体的实现步骤:
步骤1:在连接建立时提取并保存Token
SignalR连接的初始阶段是HTTP请求(之后才会升级为WebSocket或其他传输方式),所以我们可以在Hub的OnConnectedAsync方法中获取这个初始请求的HttpContext,从中提取Bearer Token并存储到连接的上下文容器中:
public override async Task OnConnectedAsync() { var httpContext = Context.GetHttpContext(); if (httpContext != null) { // 从Authorization请求头中提取Bearer Token var authHeader = httpContext.Request.Headers.Authorization.FirstOrDefault(); if (!string.IsNullOrEmpty(authHeader) && authHeader.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase)) { var bearerToken = authHeader.Substring("Bearer ".Length).Trim(); // 将Token存入当前连接的Context.Items,供后续Hub方法使用 Context.Items["BearerToken"] = bearerToken; } } await base.OnConnectedAsync(); }
步骤2:在Hub方法中使用Token调用微服务
当你需要在Hub的方法里调用其他需要Token的微服务时,直接从Context.Items中取出之前保存的Token,添加到HttpClient的请求头即可:
public async Task CallMicroservice() { // 从连接上下文获取Token if (Context.Items.TryGetValue("BearerToken", out var tokenObj) && tokenObj is string bearerToken) { using var client = new HttpClient(); // 添加Bearer Token到请求头 client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", bearerToken); // 调用微服务接口 var response = await client.GetAsync("https://your-microservice-url/api/endpoint"); // 处理响应... } else { // 处理Token不存在的情况,比如返回错误给客户端 await Clients.Caller.SendAsync("TokenMissingError"); } }
额外注意事项
- 客户端配置:确保你的SignalR客户端在连接时将Bearer Token添加到初始请求的Authorization头中。比如.NET客户端可以这样配置:
JavaScript客户端则可以通过var connection = new HubConnectionBuilder() .WithUrl("https://your-hub-url", options => { options.AccessTokenProvider = () => Task.FromResult("user-session-token"); }) .Build();accessTokenFactory配置:const connection = new signalR.HubConnectionBuilder() .withUrl("/hub", { accessTokenFactory: () => "user-session-token" }) .build(); - Token过期处理:如果Token有过期时间,你需要考虑在Token过期时如何刷新并更新连接上下文里的Token。可以通过客户端监听Token过期事件,重新连接Hub并携带新的Token,或者在Hub中检测Token有效性,触发客户端刷新Token后重新连接。
内容的提问来源于stack exchange,提问作者Luka
相关产品推荐
相关产品推荐

