ClaimsIdentity过期时间不符设定:配置1小时却15分钟失效
嘿,我碰到过好几个开发者遇到这个一模一样的问题,大概率是下面几个容易忽略的点导致的,咱们一步步排查:
1. 先检查CookieAuthenticationOptions的完整配置
你提到已经设了ExpireTimeSpan,但可能漏了关键的SlidingExpiration配置,或者其他参数冲突。完整的配置应该确保这两个参数搭配正确,比如:
public void Configuration(IAppBuilder builder) { builder.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, AuthenticationMode = AuthenticationMode.Active, LoginPath = new PathString("/Account/Login"), ExpireTimeSpan = TimeSpan.FromHours(1), // 你的1小时设置 SlidingExpiration = true, // 划重点!如果设为false,哪怕用户一直在操作,也会严格1小时后过期;设为true的话,用户活跃时会自动刷新过期时间 CookieHttpOnly = true, CookieSecure = CookieSecureOption.SameAsRequest }); }
虽然SlidingExpiration默认是true,但有时候会被其他配置覆盖,或者你在创建ClaimsIdentity时手动设了过期时间,导致Cookie的配置不生效。
2. 排查ClaimsIdentity是否被手动设置了过期时间
当你创建ClaimsIdentity的时候,有没有手动加过Expiration类型的Claim?比如下面这种代码:
var identity = new ClaimsIdentity(DefaultAuthenticationTypes.ApplicationCookie); // 要是加了这个,会直接覆盖CookieAuthenticationOptions里的过期设置 identity.AddClaim(new Claim(ClaimTypes.Expiration, DateTime.UtcNow.AddMinutes(15).ToString()));
如果有这种代码,那肯定会15分钟就过期,要么删掉这条Claim,要么把过期时间改成1小时。
3. 检查ASP.NET Session的超时设置
如果你的项目用到了Session,它的超时时间可能会和身份验证Cookie关联,尤其是用InProc模式的时候。去web.config里看看sessionState的配置:
<system.web> <sessionState mode="InProc" timeout="60" /> <!-- 这里要设成和Cookie过期时间一致或者更长,比如60分钟 --> </system.web>
要是Session超时设成了15分钟,应用程序池回收时Session丢失,可能连带身份验证Cookie也失效,导致用户被登出。
4. 别忽略应用程序池的回收时间!
这是最容易被漏掉的点!如果你的服务器上应用程序池的“固定时间间隔回收”设成了15分钟,那每次回收时,内存里的身份验证票据(默认用MachineKey保护,没持久化的话)就会失效,用户直接被踢下线。
去IIS里检查一下:
- 打开IIS管理器,找到你的应用程序池
- 右键选“高级设置”
- 看“回收”板块的“固定时间间隔(分钟)”,默认是1740分钟(29小时),要是被改成15分钟,赶紧改回正常值,或者禁用固定时间回收,改用内存占用等其他回收条件
5. 检查MachineKey配置(多服务器或频繁回收场景)
如果你的应用部署在多台服务器上,或者应用程序池经常回收,要是MachineKey是自动生成的,每次回收后密钥会变,导致之前的Cookie无法解密,用户直接登出。这时候得在web.config里手动配置固定的MachineKey:
<system.web> <machineKey validationKey="生成的验证密钥" decryptionKey="生成的解密密钥" validation="SHA1" decryption="AES" /> </system.web>
你可以用专门的工具生成固定的MachineKey,确保每次应用程序池回收后密钥不变。
按照上面的步骤逐一排查,应该就能找到问题根源啦。
内容的提问来源于stack exchange,提问作者Shadam

