How to know when OWIN cookie will expire?
.net, asp.net-mvc-5, owin, session-cookies
Solution
All you need is to get hold of the `CookieValidateIdentityContext` during the cookie validation stage. Once you get it, extract whatever you need and keep them as `Claim` or some other way that you prefer.
For MVC 5 with Asp.NET Identity 2.0, you need to perform two steps:
Define custom `OnValidateIdentity`, extract cookie information, and keep it as `Claim`.
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);
}
}
Access your `Claim` in your controller methods
// 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;
}
I use this approach to remind my application users to extend their session before session time out.
Credit to this post How do I access Microsoft.Owin.Security.xyz OnAuthenticated context AddClaims values?
Problem
I would like to create some kind of countdown timer based on the time the OWIN cookie will expire. I am using OWIN with MVC 5 and from what I understand SlidingExpiration is on by default. I do not use 'session' as I need this app to live within a web farm (I dont plan on deploying a session database).