如何避免特定请求重置OWIN Cookie超时时间?
你遇到的这个问题很典型——ASP.NET Identity的滑动过期默认会对所有经过身份验证的请求重置Cookie的过期时间,包括你用来获取剩余超时的GetCookieExpireTime接口。要避免这种情况,我们可以通过自定义CookieAuthenticationProvider来拦截身份验证流程,对特定请求跳过滑动过期的更新逻辑。
具体实现步骤
1. 配置自定义Cookie认证提供者
在你的Owin Startup类(通常是Startup.cs)中,修改Cookie认证的配置,添加自定义的OnValidateIdentity逻辑,判断请求路径来跳过指定接口的滑动过期更新:
app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, LoginPath = new PathString("/Account/Login"), SlidingExpiration = true, // 保持全局滑动过期开启 Provider = new CookieAuthenticationProvider { OnValidateIdentity = context => { // 检查当前请求是否是不需要重置过期的接口 var requestPath = context.Request.Path.Value; if (requestPath.Equals("/Home/GetCookieExpireTime", StringComparison.OrdinalIgnoreCase)) { // 跳过滑动过期更新,直接返回验证成功 return Task.CompletedTask; } // 其他请求继续执行默认的滑动过期验证逻辑 return SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>( validateInterval: TimeSpan.FromMinutes(30), regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))(context); } } });
2. 优化GetCookieExpireTime接口的时间获取逻辑
你当前从Claim中读取过期时间的方式存在误差——滑动过期会更新Cookie的实际过期时间,但Claim是登录时写入的,不会自动同步更新。建议直接从Cookie的认证票据中读取真实的过期时间:
[HttpGet] public int GetCookieExpireTime() { // 获取身份验证Cookie var authCookie = Request.Cookies[CookieAuthenticationDefaults.CookiePrefix + DefaultAuthenticationTypes.ApplicationCookie]; if (authCookie != null) { // 解析Cookie中的认证票据 var authResult = HttpContext.GetOwinContext().Authentication.AuthenticateAsync(DefaultAuthenticationTypes.ApplicationCookie).Result; if (authResult != null && authResult.Properties.ExpiresUtc.HasValue) { var remainingSeconds = (authResult.Properties.ExpiresUtc.Value - DateTimeOffset.UtcNow).TotalSeconds; // 确保返回值不小于0 return Convert.ToInt32(Math.Max(remainingSeconds, 0)); } } return 0; }
3. 逻辑说明
默认的SecurityStampValidator.OnValidateIdentity方法在验证通过后,会判断是否满足滑动过期条件(比如剩余时间不足过期时长的一半),如果满足就调用RenewIssuedCookieAsync更新Cookie的过期时间。我们通过判断请求路径,对GetCookieExpireTime接口跳过这个更新步骤,从而避免重置会话超时。
额外注意事项
- 你的
KeepSessionAlive.ashx接口不需要加入跳过列表,这样用户点击弹窗的"Continue"按钮时,能正常触发滑动过期来延长会话。 - 如果还有其他仅用于查询状态的AJAX请求,都可以按照相同的方式加入到
OnValidateIdentity的路径判断中。
内容的提问来源于stack exchange,提问作者Vetri Selvan
相关产品推荐
相关产品推荐

