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

ASP.NET Core Angular项目如何获取SignalR连接的IdentityServer4登录用户

解决步骤

  1. Angular端SignalR连接配置修正
    WebSocket协议无法自定义请求头,所以SignalR客户端需要将JWT令牌放在查询参数中传输,配置连接时使用accessTokenFactory传入你的IdentityServer4颁发的访问令牌:
import { HubConnectionBuilder } from '@microsoft/signalr';

// 示例代码,token从你的Identity存储逻辑中获取
const token = yourAuthService.getAccessToken();
this.hubConnection = new HubConnectionBuilder()
  .withUrl('https://你的后端地址/你的hub路径', {
    accessTokenFactory: () => token
  })
  .build();
  1. 后端JWT认证逻辑适配SignalR
    默认JWT认证中间件只会从Authorization请求头读取令牌,你需要配置中间件从查询参数中读取SignalR请求的令牌,注意配置顺序必须放在AddAuthentication和AddJwtBearer之后:
using Microsoft.AspNetCore.Authentication.JwtBearer;

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        // 这里放你原本的IdentityServer4 JWT配置,比如Authority、Audience等
        options.Authority = "你的IdentityServer4地址";
        options.Audience = "你的API资源名称";
    });

// 新增配置,处理SignalR的令牌读取
services.PostConfigure<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme, options =>
{
    options.Events ??= new JwtBearerEvents();
    options.Events.OnMessageReceived = context =>
    {
        var accessToken = context.Request.Query["access_token"];
        var requestPath = context.HttpContext.Request.Path;
        // 只处理对应Hub路径的请求
        if (!string.IsNullOrEmpty(accessToken) && requestPath.StartsWithSegments("/你的hub路径"))
        {
            context.Token = accessToken;
        }
        return Task.CompletedTask;
    };
});
  1. IUserIdProvider实现与注册
    首先要避免Claim映射问题,ASP.NET Core默认会将JWT中的sub声明映射为ClaimTypes.NameIdentifier,如果映射未生效可以直接读取sub声明,同时必须将自定义的IUserIdProvider注册到依赖注入容器:
// 自定义IUserIdProvider实现
public class CustomUserIdProvider : IUserIdProvider
{
    public string GetUserId(HubConnectionContext connection)
    {
        return connection.User?.FindFirst(ClaimTypes.NameIdentifier)?.Value 
            ?? connection.User?.FindFirst("sub")?.Value;
    }
}

// 在Program.cs/Startup.cs中注册
services.AddSingleton<IUserIdProvider, CustomUserIdProvider>();
  1. Hub添加认证特性
    必须在你的Hub类上添加[Authorize]特性,才会触发认证逻辑填充User对象:
[Authorize]
public class YourHub : Hub
{
    // 你的Hub逻辑
    public override async Task OnConnectedAsync()
    {
        // 此时Context.User已经有身份信息
        var userId = Context.UserIdentifier; // 直接获取IUserIdProvider返回的用户ID
        await base.OnConnectedAsync();
    }
}

完成以上配置后,你就可以直接使用hub.Clients.User(userId).SendAsync(...)向指定用户定向推送消息。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 07:24:04