Я хотел бы создать какой-то таймер обратного отсчета на основе времени истечения срока действия файла cookie OWIN. Я использую OWIN с MVC 5 и, насколько я понимаю, SlidingExpiration включен по умолчанию. Я не использую сеанс, так как мне нужно, чтобы это приложение работало в веб-ферме (я не планирую развертывание базы данных сеанса).
Как узнать, когда истечет срок действия файла cookie OWIN?
Ответы (2)
Все, что вам нужно, это получить CookieValidateIdentityContext
на этапе проверки файлов cookie. Как только вы его получите, извлеките все, что вам нужно, и сохраните их как Claim
или каким-либо другим способом, который вы предпочитаете.
Для MVC 5 с Asp.NET Identity 2.0 необходимо выполнить два шага:
Определите пользовательский
OnValidateIdentity
, извлеките информацию о файлах cookie и сохраните ее как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); } }
Получите доступ к
Claim
в методах вашего контроллера// 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; }
Я использую этот подход, чтобы напомнить пользователям моего приложения о продлении сеанса до истечения времени сеанса.
Кредит на этот пост Как мне получить доступ Значения AddClaims контекста Microsoft.Owin.Security.xyz OnAuthenticated?
stampValidator.Invoke(context);
ожидается и его следует ждать! Из-за этого у меня было неприятное исключение;)
- person jgasiorowski; 07.05.2018
SlidingExpiration
на true
для CookieAuthenticationOptions
. Это продлит срок действия файла cookie, когда пользователь делает новые HTTP-запросы во второй половине своего сеанса. Но если срок действия куки-файла аутентификации формы действительно истек, пользователь должен снова войти в систему.
- person Phyo; 08.08.2019
Я просто хочу основываться на первом ответе, у меня были проблемы с его работой, поскольку я использовал пользовательское хранилище. хотя реализация мне кажется проще
public static class ApplicationCookieValidateIdentityContext
{
public static Task ApplicationValidateIdentity(CookieValidateIdentityContext context)
{
var identity = context.Identity;
if (identity.HasClaim(c => c.Type == "expires"))
{
var existingClaim = identity.FindFirst( "expires");
identity.RemoveClaim(existingClaim);
}
if (context.Properties.ExpiresUtc == null) return Task.FromResult(0);
context.Identity.AddClaim(new Claim("expires", context.Properties.ExpiresUtc.ToString()));
return Task.FromResult(0);
}
}
Я также создал фильтр, который добавляет срок действия файла cookie.
// make sure its defaulted because the claim is not set on the login callback
var expires = DateTimeOffset.Now.AddMinutes(
Convert.ToDouble(ConfigurationManager.AppSettings["SessionTimeInMinutes"]));
if (identity.HasClaim(c => c.Type == "expires"))
{
expires = DateTimeOffset.Parse(identity.FindFirstValue("expires"));
}
cookieHeaderValues.Add(new SessionCookeHeaderValue("expiresAt", expires.ToString("O"), expires));
SlidingExpiration
stackoverflow.com/a/59038642/338456
- person Ricardo Saracino; 25.11.2019