如何知道 OWIN cookie 何时到期?

Posted

技术标签:

【中文标题】如何知道 OWIN cookie 何时到期?【英文标题】:How to know when OWIN cookie will expire? 【发布时间】:2014-05-30 05:16:48 【问题描述】:

我想根据 OWIN cookie 的过期时间创建某种倒数计时器。我将 OWIN 与 MVC 5 一起使用,据我所知,默认情况下 SlidingExpiration 处于打开状态。我不使用“会话”,因为我需要这个应用程序存在于网络场中(我不打算部署会话数据库)。

【问题讨论】:

这不可能吗? 【参考方案1】:

我只想建立在第一个答案的基础上,我在使用自定义用户商店时遇到了问题。虽然实现对我自己来说似乎更简单

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 考虑在内的解决方案***.com/a/59038642/338456【参考方案2】:

您只需在 cookie 验证阶段获取CookieValidateIdentityContext。一旦你得到它,提取你需要的任何东西并将它们保存为Claim或你喜欢的其他方式。

对于带有 Asp.NET Identity 2.0 的 MVC 5,您需要执行两个步骤:

    定义自定义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;
    
    

我使用这种方法来提醒我的应用程序用户在会话超时之前延长他们的会话。

感谢这篇文章How do I access Microsoft.Owin.Security.xyz OnAuthenticated context AddClaims values?

【讨论】:

您有运行此代码的工作项目吗?努力了解如何处理 ar stampValidator = SecurityStampValidator.OnValidateIdentity。 MyUser>(TimeSpan.FromSeconds(100), null);因为我没有 User Manager 类,而我的 User 类只是一个 DTO '我使用这种方法来提醒我的应用程序用户在会话超时之前延长他们的会话。' - 如何在不延长到期时间的情况下获得到期时间?也许相关 - 你是否启用了slidingexpiration? 这对我很有帮助。但值得注意的是stampValidator.Invoke(context); 是等待的,应该等待!因此,我遇到了令人讨厌的例外;) 一个好主意,但对我来说,这些声明从未在我的实现中持续存在,并且在控制器中不可用。我必须使用 _userManager.AddClaim(user.Id, new Claim(i.ClaimTypeName, i.ClaimTypeValue));保存索赔。因此,我添加了一个类实例的静态列表,用于存储键入用户名的值。这可能不是在网络农场上使用的方式,但在数据库中存储加密记录是一种选择 @phyo 你知道会话过期后如何延长它吗?

以上是关于如何知道 OWIN cookie 何时到期?的主要内容,如果未能解决你的问题,请参考以下文章

是否可以配置 OWIN Cookie 身份验证以防止某些 URL 影响滑动过期?

如何将 Azure OpenIdConnect OWIN 中间件 Cookie Auth 转换为 SPA 应用程序的 JavaScript JWT?

如何在不保留任何到期时间的情况下清除 javascript 中的 cookie [重复]

将cookie添加到chromedriver时如何修复Selenium中的“无效参数:无效'到期'”?

IsPersistent 在 OWIN Cookie 身份验证中的工作原理

在与一个 IIS 应用程序连接的两个域之间共享 OWIN 身份验证 Cookie