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

Blazor集成Azure SignalR遇无效协商响应,求认证解决方案

Blazor集成Azure SignalR认证问题解决方案

一、排查并修复认证相关配置

出现"Invalid negotiation response received"错误,核心原因多为Hub连接未携带有效认证凭据,或服务器端认证规则配置缺失。按以下步骤逐一调整:

1. 服务器端配置认证与授权中间件

在Program.cs中添加认证服务(以通用JWT认证为例),并为Hub启用授权校验:

// 配置JWT认证
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = builder.Configuration["Jwt:Issuer"],
            ValidAudience = builder.Configuration["Jwt:Audience"],
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]))
        };
        // 适配SignalR协议:从查询字符串读取令牌(WebSockets无法通过Header传递时的 fallback)
        options.Events = new JwtBearerEvents
        {
            OnMessageReceived = context =>
            {
                var accessToken = context.Request.Query["access_token"];
                var path = context.HttpContext.Request.Path;
                if (!string.IsNullOrEmpty(accessToken) && path.StartsWithSegments("/messagehub"))
                {
                    context.Token = accessToken;
                }
                return Task.CompletedTask;
            }
        };
    });

// 添加授权服务
builder.Services.AddAuthorization();

// 中间件管道中启用认证、授权(需放在MapHub之前)
app.UseAuthentication();
app.UseAuthorization();

// 映射Hub时强制要求授权
app.MapHub<MessageHub>("/messagehub").RequireAuthorization();

2. Blazor客户端携带认证令牌连接Hub

在Blazor组件中,获取当前用户的认证令牌并附加到SignalR连接请求中:

@inject IAccessTokenProvider TokenProvider
@inject NavigationManager NavigationManager
@using Microsoft.AspNetCore.SignalR.Client
@implements IAsyncDisposable

@code {
    private HubConnection _hubConnection;

    protected override async Task OnInitializedAsync()
    {
        var tokenResult = await TokenProvider.RequestAccessToken();
        if (tokenResult.TryGetToken(out var token))
        {
            _hubConnection = new HubConnectionBuilder()
                .WithUrl(NavigationManager.ToAbsoluteUri("/messagehub"), options =>
                {
                    options.AccessTokenProvider = () => Task.FromResult(token.Value);
                })
                .Build();

            try
            {
                await _hubConnection.StartAsync();
            }
            catch (Exception ex)
            {
                Console.WriteLine($"连接失败: {ex.Message}");
            }
        }
    }

    public async ValueTask DisposeAsync()
    {
        if (_hubConnection != null)
        {
            await _hubConnection.DisposeAsync();
        }
    }
}

3. 检查并修复CORS配置

跨域配置错误也会导致协商请求失败,在Program.cs中添加适配SignalR的CORS策略:

builder.Services.AddCors(options =>
{
    options.AddPolicy("SignalRCors", policy =>
    {
        policy.WithOrigins("https://your-blazor-app-domain.com") // 替换为你的应用实际域名
              .AllowAnyHeader()
              .AllowAnyMethod()
              .AllowCredentials();
    });
});

// 启用CORS(需放在UseRouting之前)
app.UseCors("SignalRCors");

同时确保Azure SignalR服务后台的CORS设置中已添加你的应用域名。

4. 调整Azure SignalR服务模式

针对Blazor Server应用,需开启会话粘性模式,避免因路由跳转导致的协商失败:

builder.Services.AddSignalR().AddAzureSignalR(options =>
{
    options.ServerStickyMode = ServerStickyMode.Required;
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 02:36:23