Asp.Net Core+Angular站点IIS重启后Cookie认证失效求助
问题根源分析
你遇到的这个问题,核心原因是ASP.NET Core默认的Data Protection加密密钥存储在内存中。当IIS重启或应用池回收时,内存中的密钥会被清除,而之前生成的认证Cookie是用这些密钥加密的——密钥没了,系统就无法解密Cookie,自然会把用户判定为未登录,需要重新验证身份。
你的代码里已经设置了ExpireTimeSpan = TimeSpan.FromDays(7)和SlidingExpiration = true,这部分逻辑是对的,但缺少了密钥持久化的关键配置,才导致重启后Cookie直接失效。
解决方案:持久化Data Protection密钥
要解决这个问题,你需要配置Data Protection系统将加密密钥存储到持久化介质(比如文件系统、数据库等),这样即使应用重启,密钥依然存在,就能正常解密之前的Cookie。下面是具体实现步骤:
1. 添加Data Protection持久化配置
在ConfigureServices方法开头,添加Data Protection的配置,指定密钥存储路径和应用名称:
services.AddDataProtection() // 替换成你服务器上的实际路径,建议放在非网站根目录的安全位置 .PersistKeysToFileSystem(new DirectoryInfo(@"C:\MyApp_DataProtectionKeys")) // 给你的应用设置一个唯一名称,确保同一应用的不同实例/重启后使用同一密钥集 .SetApplicationName("MyWebApp");
注意:要给这个目录分配IIS应用池账户的读写权限(比如
IIS AppPool\你的应用池名称),否则系统无法保存或读取密钥。
2. 优化Cookie认证配置(可选但推荐)
你可以进一步完善Cookie的配置,增强安全性并避免意外问题:
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(options => { options.SlidingExpiration = true; options.ExpireTimeSpan = TimeSpan.FromDays(7); options.LoginPath = "/Identity/Login"; options.LogoutPath = "/Identity/Logout"; options.Cookie.IsEssential = true; // 显式设置Cookie名称,避免默认值变更导致的问题 options.Cookie.Name = ".MyWebApp.AuthCookie"; // 开启HttpOnly,防止XSS攻击窃取Cookie options.Cookie.HttpOnly = true; // 生产环境强制HTTPS传输Cookie,确保安全 options.Cookie.SecurePolicy = CookieSecurePolicy.Always; });
完整修改后的ConfigureServices代码
public void ConfigureServices(IServiceCollection services) { // 配置Data Protection,持久化密钥到文件系统 services.AddDataProtection() .PersistKeysToFileSystem(new DirectoryInfo(@"C:\MyApp_DataProtectionKeys")) .SetApplicationName("MyWebApp"); services.AddDbContext<MyAppContext>(options => options.UseMySql(connectionString)); services.AddIdentity<ApplicationUser, ApplicationRole>(options => { options.User.RequireUniqueEmail = true; options.SignIn.RequireConfirmedEmail = true; }) .AddEntityFrameworkStores<MyAppContext>() .AddDefaultTokenProviders(); services.AddAuthorization(); services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(options => { options.SlidingExpiration = true; options.ExpireTimeSpan = TimeSpan.FromDays(7); options.LoginPath = "/Identity/Login"; options.LogoutPath = "/Identity/Logout"; options.Cookie.IsEssential = true; options.Cookie.Name = ".MyWebApp.AuthCookie"; options.Cookie.HttpOnly = true; options.Cookie.SecurePolicy = CookieSecurePolicy.Always; }); }
额外注意事项
- 多服务器部署:如果你的应用跑在多台服务器(负载均衡)上,要确保所有服务器都能访问同一个密钥存储位置(比如共享网络文件夹、Azure Blob存储),或者改用分布式存储(如Redis、SQL Server)来存储密钥。
- 密钥轮换:Data Protection会自动处理密钥轮换,旧密钥会被保留用于解密旧Cookie,直到它们过期,无需手动干预。
- 生产环境安全:密钥存储目录要远离网站根目录,避免被恶意访问;永远不要将密钥提交到代码仓库。
这样配置后,即使IIS重启或应用池回收,用户的认证Cookie依然能被正常解密,登录状态会保持7天(如果用户7天内有操作,滑动过期会自动延长有效期)。
内容的提问来源于stack exchange,提问作者antonad
相关产品推荐
相关产品推荐

