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

为Blazor应用Hub添加[Authorize]后WebSocket连接失败求助

Blazor SignalR添加[Authorize]后无法建立WSS连接排查方案

问题描述

给SignalR的PaymentHub添加[Authorize]特性后,Blazor应用无法建立WSS连接,但普通HTTP请求可正常工作;浏览器网络面板未显示401错误,连接状态仅标注"finished",使用Visual Studio 17.6(已排除旧版本VS Code相关bug)。

Hub实现代码

using Duende.IdentityServer.Extensions;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.SignalR;
using System.Security.Claims;

namespace BagiBagiDev.Server.Hubs
{
    [Authorize]
    public class PaymentHub : Hub
    {
        public async Task TestMessage(string user, string message)
        {
            await Clients.All.SendAsync("ReceiveMessage", user, message);
        }
        public override async Task OnConnectedAsync()
        {
            var username = Context.User.FindFirst(c => c.Type == ClaimTypes.Name).Value;
            if (!string.IsNullOrEmpty(username))
            {
                await Groups.AddToGroupAsync(Context.ConnectionId, username);
            }
            await base.OnConnectedAsync();
        }
    }
}

排查与解决步骤

1. 检查客户端令牌传递逻辑

Blazor WebAssembly场景下,SignalR客户端需显式传递认证令牌,确保客户端连接代码配置了AccessTokenProvider:

var hubConnection = new HubConnectionBuilder()
    .WithUrl(NavigationManager.ToAbsoluteUri("/paymentHub"), options =>
    {
        options.AccessTokenProvider = async () =>
        {
            var accessTokenResult = await TokenProvider.RequestAccessToken();
            accessTokenResult.TryGetToken(out var accessToken);
            return accessToken?.Value ?? string.Empty;
        };
    })
    .Build();

Blazor Server场景下,若涉及跨域需额外配置令牌转发,确保当前上下文认证信息能传递到SignalR连接。

2. 修复OnConnectedAsync中的空引用风险

当前OnConnectedAsync未做空值校验,若用户未正确认证(令牌无效/缺失),Context.User或目标声明可能为null,抛出的异常会直接终止连接(无401响应)。修改代码添加校验:

public override async Task OnConnectedAsync()
{
    var usernameClaim = Context.User?.FindFirst(ClaimTypes.Name);
    if (usernameClaim != null && !string.IsNullOrEmpty(usernameClaim.Value))
    {
        await Groups.AddToGroupAsync(Context.ConnectionId, usernameClaim.Value);
    }
    await base.OnConnectedAsync();
}

可追加日志记录连接异常,便于定位问题:

private readonly ILogger<PaymentHub> _logger;

public PaymentHub(ILogger<PaymentHub> logger)
{
    _logger = logger;
}

public override async Task OnConnectedAsync()
{
    try
    {
        var usernameClaim = Context.User?.FindFirst(ClaimTypes.Name);
        if (usernameClaim != null && !string.IsNullOrEmpty(usernameClaim.Value))
        {
            await Groups.AddToGroupAsync(Context.ConnectionId, usernameClaim.Value);
        }
        await base.OnConnectedAsync();
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, "SignalR连接时发生错误");
        throw;
    }
}

3. 验证令牌权限与声明

确认IdentityServer颁发的令牌包含:

  • name声明(对应ClaimTypes.Name)
  • 若[Authorize]指定了策略,需确保令牌包含对应角色/权限声明

4. 查看服务器端详细日志

在appsettings.json中开启SignalR相关调试日志,获取连接失败的具体原因:

{
    "Logging": {
        "LogLevel": {
            "Microsoft.AspNetCore.SignalR": "Debug",
            "Microsoft.AspNetCore.Http.Connections": "Debug"
        }
    }
}

5. 检查WebSocket协议支持

  • IIS部署时需启用WebSocket功能
  • 反向代理(如Nginx)需配置WebSocket代理规则,确保Upgrade请求被正确转发

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 18:43:14