.NET Core应用迁移生产环境后出现用户随机登出问题
ASP.NET Core Identity 生产环境随机登出问题解决指南
测试服务器开发应用期间全程未出现任何问题,但将其迁移至不同的生产服务器后,内置Core Identity开始出现多个问题。用户登录后,浏览器可正常存储identity token,用户也能正常访问所有页面,但经过若干次页面跳转后应用会突然将用户登出。此时浏览器中仍保存有该token,但看起来已失效。该问题发生时机完全随机,有时仅跳转一次就出现,有时要经过多次页面跳转或刷新才会出现。
该问题90%以上的场景由数据保护密钥未同步/未持久化导致,其余常见触发原因和解决方法如下:
- 优先排查数据保护密钥配置
ASP.NET Core默认使用Data Protection机制加密Identity的Cookie和Token,默认密钥存储在内存或者当前运行用户的本地目录中,仅单实例本地部署时可用。如果生产环境是多实例负载均衡部署、容器化部署且未做持久化挂载、或者应用运行权限不足无法读取本地密钥目录,就会出现请求打到不同节点、或者应用重启后密钥不匹配的情况,无法解密已有的Token,触发随机登出。
解决方法是将密钥持久化到所有实例可访问的公共存储,示例配置如下:
// 本地多实例可使用共享目录存储密钥 builder.Services.AddDataProtection() .PersistKeysToFileSystem(new DirectoryInfo(@"\\共享目录路径\data-protection-keys")) .SetDefaultKeyLifetime(TimeSpan.FromDays(180)); // 容器/分布式部署可选择Redis存储密钥 // 需要安装Microsoft.AspNetCore.DataProtection.StackExchangeRedis包 builder.Services.AddDataProtection() .PersistKeysToStackExchangeRedis(ConnectionMultiplexer.Connect("你的Redis连接串"), "DataProtection-Keys");
- 检查负载均衡与HTTPS转发配置
如果生产环境有负载均衡做HTTPS卸载,需要配置转发头让应用可以正确识别请求协议,否则会因为请求是HTTP协议但Cookie设置了Secure属性,导致身份验证失败。配置示例:
builder.Services.Configure<ForwardedHeadersOptions>(options => { options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto; // 添加上游负载均衡的IP到信任列表 options.KnownProxies.Add(IPAddress.Parse("192.168.1.100")); }); // 该中间件必须放在所有中间件的最靠前位置 app.UseForwardedHeaders();
临时修复可开启负载均衡的会话亲和性(粘性会话),保证同一用户的所有请求都打到同一个应用节点,避免密钥不匹配问题,但该方案无法解决应用重启后的登出问题,仅做临时应急使用。
- 核对Identity Cookie配置
检查是否误配置了过短的Cookie有效期、或者滑动过期逻辑异常,示例标准配置:
builder.Services.ConfigureApplicationCookie(options => { options.ExpireTimeSpan = TimeSpan.FromHours(2); options.SlidingExpiration = true; options.Cookie.SameSite = SameSiteMode.Lax; // 生产环境必须开启Secure,仅HTTPS请求可携带Cookie options.Cookie.SecurePolicy = CookieSecurePolicy.Always; });
内容的提问来源于stack exchange,提问作者Kamil Brucki
相关产品推荐
相关产品推荐

