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

.NET 6 SignalR通知服务中JWT Token获取为null的问题

.NET 6 SignalR中通过查询参数Token获取用户数据始终为null的问题

我正在使用.NET 6.0中的SignalR开发通知服务,需要通过查询参数里的Token获取用户数据,但Token相关的用户ID始终为null,找不到相关解决信息,不知如何处理。

Program.cs 代码

builder.Services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(o =>
{
    o.TokenValidationParameters = new TokenValidationParameters
    {
        //ValidIssuer = builder.Configuration["Jwt:Issuer"],
        // ValidAudience = builder.Configuration["Jwt:Audience"],

        IssuerSigningKey = new SymmetricSecurityKey
            (Encoding.UTF8.GetBytes(builder.Configuration["secreatKey"])),
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidateLifetime = false,
        ValidateIssuerSigningKey = true
    };

    o.Events = new JwtBearerEvents
    {
        OnMessageReceived = context =>
        {
            var accessToken = context.Request.Query["access_token"];
            if (string.IsNullOrEmpty(accessToken) == false)
            {
                context.Token = accessToken;
            }

            return Task.CompletedTask;
        }
    };
});

NotificationHub 代码

public class NotificationHub : Hub<INotificationHub>
{
    private readonly NotificationMemoryStorage _notificationStorage;

    public NotificationHub(NotificationMemoryStorage notificationMemoryStorage)
    {
        _notificationStorage = notificationMemoryStorage;
    }

    public override async Task OnConnectedAsync()
    {
        
        var userId = GetUserIdFromToken();
        if(!string.IsNullOrEmpty(userId))
        {
            var notifications = _notificationStorage.GetNotifications(userId);
            foreach (var notification in notifications)
            {
                await Clients.User(userId).SendNotification(notification);
            }
            _notificationStorage.ClearNotifications(userId);
            var response = new ServerResponse
            {
                status = "Acepted",
            };
            await Clients.Client(Context.ConnectionId).ConnectionResponse(response);

        }
            await base.OnConnectedAsync();
    }

    public override async Task OnDisconnectedAsync(Exception? exception)
    {
        await base.OnDisconnectedAsync(exception);
    }

    public async Task MessageCheck(NotificationRequestModel request)
    {
        switch (request.Target.Device)
        {
            case "Admin":
                if (request.Target.User.Contains("*"))
                {
                    SendNotificationToAllUsers(request.Notification);
                }
                else
                {
                    //SendNotificationToSpecificUser(request, request.Target.User);
                }
                break;
        }
    }

    public async Task SendNotificationToAllUsers(NotificationModel message)
    {
        await Clients.All.SendNotificationToAllUsers(message);
    }
    
    private string GetUserIdFromToken()
    {
        var token = Context.GetHttpContext();
        var jwt = token.Request.Headers["access_token"];

        var identity = (ClaimsIdentity)Context.User.Identity;
        var userIdClaim = identity.FindFirst(ClaimTypes.NameIdentifier);
        return userIdClaim?.Value;
    }

    //public async Task SendNotificationToSpecificUser(NotificationRequestModel message, List<string> target)
    //{
    //    foreach (var item in target)
    //    {
    //        //if (ConnectedUsers.TryGetValue(item, out var user))
    //        //{
    //        await Clients.Client(user.ConnectionId).SendNotification(message);
    //        //}
    //    }
    //}
}

问题所在方法

以下方法中获取的userIdClaim始终为null:

private string GetUserIdFromToken()
{
    var token = Context.GetHttpContext();
    var jwt = token.Request.Headers["access_token"];

    var identity = (ClaimsIdentity)Context.User.Identity;
    var userIdClaim = identity.FindFirst(ClaimTypes.NameIdentifier);
    return userIdClaim?.Value;
}

请求截图

请求参数截图

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 16:40:36