在MVC标识(2.0.1)中,regenerateIdentity / validateInterval持续时间之后,E



我一整天都在为这件事挠头。我试图在MVC身份2.0.1中设置"非常长"的登录会话。(30天)。

我使用以下cookie启动:

      app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            SlidingExpiration = true,
            ExpireTimeSpan = System.TimeSpan.FromDays(30),
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/My/Login"),
            CookieName = "MyLoginCookie",
            Provider = new CookieAuthenticationProvider
            {                           
                OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
                    validateInterval: TimeSpan.FromMinutes(30),
                    regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
            }
        });

总的来说,工作得很好。30天后饼干就做好了,一切看起来都很好。

如果我关闭浏览器并在"validateInterval"持续时间过去(这里30分钟)后回来,我仍然登录,但是cookie现在被重新发布为"会话"(正确的cookie名称仍然)!已经过了30天的有效期。

如果我现在关闭浏览器/重新打开,我将不再登录。

我已经测试了删除"提供商"和所有工作如预期,然后,我可以回来几个小时后,我仍然登录好。我读到使用戳记重新验证是最佳实践,所以我不确定如何继续。

SecurityStampValidator触发regenerateIdentity回调时,当前认证的用户使用非持久登录重新登录。这是硬编码的,我不相信有任何方法可以直接控制它。因此,登录会话将只持续到您在重新生成身份时正在运行的浏览器会话结束。

这是一种使登录持久的方法,即使在身份再生操作中也是如此。本描述是基于使用Visual Studio MVC的ASP。. NET web项目模板。

首先,我们需要有一种方法来跟踪登录会话在不同的HTTP请求中持久化的事实。这可以通过向用户身份添加"IsPersistent"声明来实现。下面的扩展方法展示了这样做的方法。

public static class ClaimsIdentityExtensions
{
    private const string PersistentLoginClaimType = "PersistentLogin";
    public static bool GetIsPersistent(this System.Security.Claims.ClaimsIdentity identity)
    {
        return identity.Claims.FirstOrDefault(c => c.Type == PersistentLoginClaimType) != null;
    }
    public static void SetIsPersistent(this System.Security.Claims.ClaimsIdentity identity, bool isPersistent)
    {
        var claim = identity.Claims.FirstOrDefault(c => c.Type == PersistentLoginClaimType);
        if (isPersistent)
        {
            if (claim == null)
            {
                identity.AddClaim(new System.Security.Claims.Claim(PersistentLoginClaimType, Boolean.TrueString));
            }
        }
        else if (claim != null)
        {
            identity.RemoveClaim(claim);
        }
    }
}

接下来,我们需要在用户签名请求持久会话时声明"IsPersistent"。例如,您的ApplicationUser类可能有一个GenerateUserIdentityAsync方法,该方法可以更新为接受isPersistent标志参数,如下所示,以便在需要时做出这样的声明:

public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager, bool isPersistent)
{
    var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
    userIdentity.SetIsPersistent(isPersistent);
    return userIdentity;
}

ApplicationUser.GenerateUserIdentityAsync的任何调用者现在都需要传入isPersistent标志。例如,AccountController.SignInAsync中对GenerateUserIdentityAsync的调用将从

AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, 
    await user.GenerateUserIdentityAsync(UserManager));

AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent },
    await user.GenerateUserIdentityAsync(UserManager, isPersistent));

最后,需要注意Startup.ConfigureAuth方法中使用的CookieAuthenticationProvider.OnValidateIdentity委托,以保留跨身份再生操作的持久性细节。默认委托看起来像:

OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
    validateInterval: TimeSpan.FromMinutes(20),
    regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))

可以改成:

OnValidateIdentity = async (context) =>
{
    await SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
        validateInterval: TimeSpan.FromMinutes(20),
        // Note that if identity is regenerated in the same HTTP request as a logoff attempt,
        // the logoff attempt will have no effect and the user will remain logged in.
        // See https://aspnetidentity.codeplex.com/workitem/1962
        regenerateIdentity: (manager, user) =>
            user.GenerateUserIdentityAsync(manager, context.Identity.GetIsPersistent())
    )(context);
    // If identity was regenerated by the stamp validator,
    // AuthenticationResponseGrant.Properties.IsPersistent will default to false, leading
    // to a non-persistent login session. If the validated identity made a claim of being
    // persistent, set the IsPersistent flag to true so the application cookie won't expire
    // at the end of the browser session.
    var newResponseGrant = context.OwinContext.Authentication.AuthenticationResponseGrant;
    if (newResponseGrant != null)
    {
        newResponseGrant.Properties.IsPersistent = context.Identity.GetIsPersistent();
    }
}

在ASP中修复此错误。NET身份2.2。见https://aspnetidentity.codeplex.com/workitem/2319

相关内容

  • 没有找到相关文章

最新更新