具有 2FA 的 Asp.Net Identity - 记住 session 后不保留浏览器 cookie

标签 asp.net session cookies asp.net-identity

我正在使用带有 Asp.Identity 和两因素身份验证的 MVC5.2 的最新示例代码。

启用 2FA 后,当用户登录时,系统会提示输入代码(通过电话或电子邮件发送),并且他们可以选择“记住浏览器” - 这样他们就不会在该浏览器上再次要求输入代码.

这在VerifyCode操作中处理

var result = await SignInManager.TwoFactorSignInAsync(model.Provider, model.Code, isPersistent:  model.RememberMe, rememberBrowser: model.RememberBrowser);

请注意,默认模板中未使用 model.RememberMe,因此它为 false。

我发现当我这样做时,设置的.AspNet.TwoFactorRememberBrowser会在 session 结束时过期(因此它不记得浏览器)

现在,如果我设置 isPersistent = true.AspNet.TwoFactorRememberBrowser 的有效期为 30 天,这很好,但是 .AspNet.ApplicationCookie code> 也有 30 天的有效期 - 这意味着当我关闭浏览器并重新打开时,我会自动登录。

我希望它不会保留我的登录信息,但会保留我选择记住 2FA 代码的方式。即用户应该始终必须登录,但如果他们已经保存了 2fa 代码,则不应要求他们提供。

还有其他人看过这个吗,还是我错过了什么?

最佳答案

这段代码似乎并不是为了在同一请求/响应中设置多个身份 cookie 而设计的,因为 OWIN cookie 处理程序最终共享相同的 AuthenticationProperties。这是因为 AuthenticationResponseGrant 有一个主体,但主体可以有多个身份。

您可以通过更改然后恢复特定于 2FA cookie 提供程序的 ResponseSignIn 和 ResponseSignedIn 事件中的 AuthenticationProperties 来解决此错误:

        //Don't use this.
        //app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie);

        //Set the 2FA cookie expiration and persistence directly
        //ExpireTimeSpan and SlidingExpiration should match the Asp.Net Identity cookie setting
        app.UseCookieAuthentication(new CookieAuthenticationOptions()
        {
            AuthenticationType = DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie,
            AuthenticationMode = AuthenticationMode.Passive,
            CookieName = DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie,
            ExpireTimeSpan = TimeSpan.FromHours(2),
            SlidingExpiration = true,
            Provider = new CookieAuthenticationProvider
            {
                OnResponseSignIn = ctx =>
                {
                    ctx.OwinContext.Set("auth-prop-expires", ctx.Properties.ExpiresUtc);
                    ctx.OwinContext.Set("auth-prop-persist", ctx.Properties.IsPersistent);
                    var issued = ctx.Properties.IssuedUtc ?? DateTimeOffset.UtcNow;
                    ctx.Properties.ExpiresUtc = issued.AddDays(14);
                    ctx.Properties.IsPersistent = true;
                },
                OnResponseSignedIn = ctx =>
                {
                    ctx.Properties.ExpiresUtc = ctx.OwinContext.Get<DateTimeOffset?>("auth-prop-expires");
                    ctx.Properties.IsPersistent = ctx.OwinContext.Get<bool>("auth-prop-persist");
                }
            }
        });

确保设置与您的主 Asp.Net Identity cookie 相同的 ExpireTimeSpan 和 SldingExpiration 以保留这些设置(因为它们会合并到 AuthenticationResponseGrant 中)。

关于具有 2FA 的 Asp.Net Identity - 记住 session 后不保留浏览器 cookie,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28745143/

相关文章:

c# - 如何在 ASP.NET 中实现 GZip 压缩?

asp.net - 如何停止所有卡西尼实例?

php - Laravel 和 Redis : session driver 'array'

javascript - Node js session 覆盖我的第一个 session

c# - 在 mvc razor 中编码或解码保存在 cookie 中的空间

javascript - 如何将用户输入从 ASP.NET TextBox 传递到 JavaScript 函数?

asp.net - ASP.NET 4.0 中最好的浏览器检测解决方案

java - 如何在 Struts 2 中更改 JSESSIONID

javascript - 添加 Cookie 以维护 jQuery Mobile 页面的字体大小

php - 限制每日访问