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

Blazor Hosted WebAssembly在K8s多副本下的认证异常问题

问题分析与解决方案

问题背景

基于.NET 8的Blazor Hosted WebAssembly应用,采用客户端+服务端架构,已配置Cookie认证授权。本地、Azure WebApp或K8s单副本运行正常,但K8s副本数超过1时,出现认证失效、SignalR方法失败的情况,刷新页面偶尔成功(符合轮询负载均衡的表现),控制台输出user_not_authorized。

核心问题:数据保护密钥未跨实例共享

你的服务端并非主动存储用户状态,但Cookie认证的核心依赖加密的认证Ticket——服务端用数据保护密钥加密Ticket并存入Cookie,后续请求时解密Ticket获取用户身份。当K8s多副本运行时,每个实例默认会生成独立的数据保护密钥,导致:

  • 用户在实例A登录,得到用A的密钥加密的Cookie
  • 后续请求被负载均衡转发到实例B,B用自己的密钥无法解密Cookie,直接判定用户未授权

看你的Program.cs配置:

options.DataProtectionProvider = DataProtectionProvider.Create(Parameters.app_protector);

这里用Create方法创建的是本地临时密钥环,每个服务实例启动时都会生成完全独立的密钥,这就是多副本认证失效的根源。

其他潜在问题点

  1. 异步调用错误:校验控制器里用_authorizationService.AuthorizeAsync(User, UserPolicy).Result同步阻塞调用异步方法,可能引发线程上下文异常,导致身份信息读取失败。
  2. Cookie配置细节:虽然当前Cookie是Strict模式,但如果负载均衡的域名/路径不一致,也可能导致Cookie无法携带,但单副本运行正常,这个概率较低。

解决方案

1. 共享数据保护密钥(最关键)

必须让所有服务端实例使用相同的数据保护密钥环,推荐两种持久化方式:

方式一:用Redis存储密钥

// 先安装NuGet包:Microsoft.AspNetCore.DataProtection.StackExchangeRedis
builder.Services.AddDataProtection()
    .PersistKeysToStackExchangeRedis(ConnectionMultiplexer.Connect("你的Redis连接字符串"), "DataProtection-Keys")
    .SetApplicationName(Parameters.app_protector); // 保持和原配置的应用名称一致

然后修改Cookie认证配置,替换为共享的密钥实例:

.AddCookie(options =>
{
    options.DataProtectionProvider = builder.Services.BuildServiceProvider().GetRequiredService<IDataProtectionProvider>();
    // 其他原有配置保持不变
});

方式二:用K8s Secret存储密钥文件

先导出单实例的密钥文件,存入K8s Secret后挂载到所有实例的相同路径,再配置数据保护读取该路径:

builder.Services.AddDataProtection()
    .PersistKeysToFileSystem(new DirectoryInfo("/挂载的密钥路径"))
    .SetApplicationName(Parameters.app_protector);

2. 修正异步调用问题

把校验控制器里的同步调用改成异步:

// 原代码
var authorizationResult = _authorizationService.AuthorizeAsync(User, UserPolicy).Result;
// 修改为
var authorizationResult = await _authorizationService.AuthorizeAsync(User, UserPolicy);

同时将控制器方法标记为async Task<IActionResult>。

3. 可选:配置负载均衡会话粘性

如果暂时无法配置密钥共享,可以给K8s负载均衡配置基于Cookie的会话粘性,让用户请求始终转发到同一个实例。但这只是临时方案,实例重启或扩容后仍会出现问题,密钥共享才是根本解决办法。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 16:33:27