Cookie 持久性在 OWIN 身份验证中不起作用

Posted

技术标签:

【中文标题】Cookie 持久性在 OWIN 身份验证中不起作用【英文标题】:Cookie persistence not working in OWIN authentication 【发布时间】:2020-03-19 10:15:14 【问题描述】:

我正在开发一个使用 OWIN 身份验证系统(Microsoft.Owin v4.1.0 通过 NuGet)的 MVC5 网站。我根据数据库验证用户的登录凭据,然后使用 OWIN IAuthenticationManager 登录。以下是相关代码:

using Microsoft.Owin.Security;

public class AuthManager : IAuthManager

    private readonly IAuthenticationManager AuthenticationManager;

    public AuthManager()
    
        this.AuthenticationManager = HttpContext.Current.GetOwinContext().Authentication;
    

    public void SignIn(AppUserState appUserState, bool rememberMe)
    
        AuthenticationProperties authenticationProperties = new AuthenticationProperties()
        
            AllowRefresh = true,
            IsPersistent = rememberMe,
            ExpiresUtc = DateTime.UtcNow.AddDays(14),
            IssuedUtc = DateTime.UtcNow
        ;

        List<Claim> claims = new List<Claim>();
        claims.Add(new Claim(ClaimTypes.NameIdentifier, appUserState.EmailAddress));
        claims.Add(new Claim(ClaimTypes.Name, appUserState.Name));
        claims.Add(new Claim("userState", appUserState.ToString()));

        ClaimsIdentity identity = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie);

        this.AuthenticationManager.SignIn(authenticationProperties, identity);
    

登录过程有效,但持久性无效。尽管 IsPersistent 被设置为 true,但在大约 30-60 分钟后会话总是结束。当我进入调试器并检查authenticationProperties 对象时,我可以看到IsPersistent 确实是真的。

我在网上读到,这是决定您的应用程序是否应该让您的用户保持登录状态的标志,即使用户没有积极使用该网站。但是用户的会话总是结束。

我认识到的一件事是AuthenticationProperties 类内部有一个字典对象:

当我打开字典时,我可以看到有一个标记为.persistent 的键,它有一个空白值。我尝试将此值设置为True(以复制.refresh 键的行为)-但这根本没有效果。

我认为上述问题与问题无关,但我认为我应该分享我已经进行的调查。

如何防止用户自动注销?

【问题讨论】:

【参考方案1】:

当您关闭浏览器会话时,持久性 cookie 不会被清除,它们仍然会过期。将CookieAuthenticationOptions 中的ExpireTimeSpan 设置为更长的时间。

【讨论】:

谢谢,这不是问题的原因,但您确实为我指明了正确的方向。我忘记了Startup.Auth.cs 中列出的默认身份验证步骤。【参考方案2】:

事实证明这与 cookie 过期时间无关。我尝试将 ExpireTimeSpan 设置为 14 天(作为测试),但没有任何区别 - 我仍然自动注销。

但是我正在查看相同的方法 (ConfigureAuth) 并看到我有以下代码:

app.UseCookieAuthentication(new CookieAuthenticationOptions

    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
    ExpireTimeSpan = new TimeSpan(14, 0, 0, 0, 0),
    LoginPath = new PathString("/Account/Login"),
    Provider = new CookieAuthenticationProvider
    
        OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
            validateInterval: TimeSpan.FromMinutes(30),
            regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
    
);

作为测试,我将 validateInterval: TimeSpan.FromMinutes(30), 设置为 3000 分钟。 30 分钟后我不再被注销。所以我的会话结束的原因是因为显然对 SecurityStampValidator.OnValidateIdentity 的调用返回的是当前用户未经授权!

【讨论】:

以上是关于Cookie 持久性在 OWIN 身份验证中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Owin cookie身份验证设置cookie未保存在浏览器中

在 OWIN 托管的 SignalR 实现中接受 ASP.NET 表单身份验证 cookie?

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

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

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

OWIN Cookie 身份验证 - 使用 Kerberos 委派模拟 SQL Server