Я хотел бы создать какой-то таймер обратного отсчета на основе времени истечения срока действия файла cookie OWIN. Я использую OWIN с MVC 5 и, насколько я понимаю, SlidingExpiration включен по умолчанию. Я не использую сеанс, так как мне нужно, чтобы это приложение работало в веб-ферме (я не планирую развертывание базы данных сеанса).
Вопрос
Как узнать, когда истечет срок действия файла cookie OWIN?
- Разве это невозможно? FrankO 20.04.2014
Ответы
Ответ 1 · рейтинг 38 · Phyo
Все, что вам нужно, это получить 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?
Ответ 2 · Ricardo Saracino
Я просто хочу основываться на первом ответе, у меня были проблемы с его работой, поскольку я использовал пользовательское хранилище. хотя реализация мне кажется проще
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));
Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.
Похожие материалы
- Когда я издеваюсь над своим контроллером ASP.NET MVC, мой ActionMethod не возвращает представления. Почему?
- Размер атомарного чтения / записи в 64-битных системах для .NET?
- Служба данных WCF с использованием пользовательского UserNamePasswordValidator
- Как открыть и заполнить файл .XML на листе в Excel с помощью VB.Net?
- Аутентификация с помощью файла cookie субдомена позволяет легко получить доступ к другим субдоменам.
- Как хранить и повторно использовать файлы cookie в Postman?