我想根据OWIN cookie到期的时间创建一些倒数计时器.我正在使用OWIN与MVC 5,从我的理解SlidingExpiration默认情况下打开.我不使用’会话’,因为我需要这个应用程序生活在一个网络农场(我不打算部署一个会话数据库).
解决方法
所有您需要的是在Cookie验证阶段获取CookieValidateIdentityContext.一旦你得到它,提取任何你需要的,并保持他们作为声明或其他方式,你喜欢.
对于具有Asp.NET Identity 2.0的MVC 5,您需要执行两个步骤:
>定义自定义OnValidateIdentity,提取cookie信息,并将其保留为声明.
public class Startup { public void Configuration(IAppBuilder app) { app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,Provider = new CookieAuthenticationProvider { OnValidateIdentity = MyCustomValidateIdentity //refer to the implementation below } } } // this method will be called on every request // it is also one of the few places where you can access unencrypted cookie content as CookieValidateIdentityContext // once you get cookie information you need,keep it as one of the Claims // please ignore the MyUserManager and MyUser classes,they are only for sample,you should have yours private static Task MyCustomValidateIdentity(CookieValidateIdentityContext context) { // validate security stamp for 'sign out everywhere' // here I want to verify the security stamp in every 100 seconds. // but I choose not to regenerate the identity cookie,so I passed in NULL var stampValidator = SecurityStampValidator.OnValidateIdentity<MyUserManager<Myuser>. MyUser>(TimeSpan.FromSeconds(100),null); stampValidator.Invoke(context); // here we get the cookie expiry time var expireUtc = context.Properties.ExpiresUtc; // add the expiry time back to cookie as one of the claims,called 'myExpireUtc' // to ensure that the claim has latest value,we must keep only one claim // otherwise we will be having multiple claims with same type but different values var claimType = "myExpireUtc"; var identity = context.Identity; if(identity.HasClaim(c=> c.Type == claimType)) { var existingClaim = identity.FindFirst(claimType); identity.RemoveClaim(existingClaim); } var newClaim = new Claim(claimType,expireUtc.Value.UtcTicks.ToString()); context.Identity.AddClaim(newClaim); return Task.FromResult(0); } }
>在控制器方法中访问您的声明
// since expiry time has now become part of your claims,you now can get it back easily // this example just returns the remaining time in total seconds,as a string value // assuming this method is part of your controller methods public string RemainingTime() { var identity = User.Identity as ClaimsIdentity; var claimType = "myExpireUtc"; //NOTE: must be the same key value "myExpireUtc" defined in code shown above if(identity != null && identity.HasClaim(c=> c.Type == claimType)) { var expireOn = identity.FindFirstValue(claimType); DateTimeOffset currentUtc = DateTimeOffset.UtcNow; DateTimeOffset? expireUtc = new DateTimeOffset(long.Parse(expireOn),TimeSpan.Zero); var remaining = (expireUtc.Value - currentUtc).TotalSeconds; return remaining.ToString(); } return string.Empty; }
感谢这篇文章How do I access Microsoft.Owin.Security.xyz OnAuthenticated context AddClaims values?