如何在不影响密码更改行为的情况下正确防止 ASP.NET Identity 2.2.1 中的多个活动会话?

Posted

技术标签:

【中文标题】如何在不影响密码更改行为的情况下正确防止 ASP.NET Identity 2.2.1 中的多个活动会话?【英文标题】:How do I properly prevent mulitple active sessions in ASP.NET Identity 2.2.1 without affecting password change behavior? 【发布时间】:2017-06-11 00:31:45 【问题描述】:

我需要消除我们网站上允许的多个活动会话。

据我了解,要做到这一点,您可以如下操作 CookieAuthenticationProvider 的 OnValidateIdentity 属性的 validateInterval 参数:

Provider = new CookieAuthenticationProvider
    
        // Enables the application to validate the security stamp when the user logs in.
        // This is a security feature which is used when you change a password or add an external login to your account.  
        OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
            validateInterval: TimeSpan.FromMinutes(0), //Changed from default of 30 minutes
            regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
    

我将默认值从 30 分钟更改为 0 以进行测试,它按预期工作。如果我登录到第二个浏览器,在第一个浏览器中执行的下一个操作会将我重定向到登录页面。

我还允许用户随时更改密码(登录后)。 validateInterval 属性为零时,用户在提交密码更改后立即注销。然后,他们使用新密码重新登录,即可正常使用该网站。

如果我将 validateInterval 参数值更改为 10 秒,则允许用户在提交密码更改 10 秒后继续当前会话,然后重定向到登录页面。

在 ManageController 类的 ChangePassword 操作中,密码更改成功后运行的默认代码如下:

if (result.Succeeded)


    var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
    if (user != null)
    
        await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);                    
    
    return RedirectToAction("Index", new  Message = ManageMessageId.ChangePasswordSuccess );
 

我认为即使更改密码(来自Logout User From all Browser When Password is changed),SignInManager.SignInAsync 行也会使用户的会话继续进行,但它似乎还由 validateInterval 参数控制。

如果我想允许用户在经过身份验证的会话期间更改其密码而不强制再次登录,我可以使用 ASP.NET Identity 执行此操作并仍然控制多个活动会话吗?有没有更好的方法来控制多个活动会话而不更改 validateInterval 参数(来自Prevent multiple logins)?

感谢您的帮助。澄清一下,如果这种行为是设计使然,我可以接受。我只是想了解发生了什么,以便在需要时为老板的行为辩护。

编辑:

我没有提到我还在登录操作中通过 SignInManager 直接在登录之前更新了安全标记。

【问题讨论】:

【参考方案1】:

执行您正在执行的操作不会阻止多个活动会话。我还通过“会话”假设您正在谈论同一用户帐户的多个身份验证。从最真实的意义上说,多个活跃的会话是完全不同的讨论。也就是说,为维护用户的“已验证”状态而设置的 cookie 是特定于客户端的。如果我从台式计算机和移动设备登录,甚至从同一台计算机上的 Chrome 和 Internet Explorer 登录,这些都是不同的 cookie,不受可能已在其他设备或浏览器上设置的其他 cookie 的影响。

您可以真正防止这种情况的唯一方法是以某种方式将用户标记为“已登录”服务器端(例如,用户表上的列)。然后,在其他任何地方对他们进行身份验证之前(基本上在您的登录后操作中),您将检查他们的用户帐户是否有此标志。如果它已经设置,那么您将拒绝再次登录,直到他们第一次在原始设备/浏览器上注销。显然,您的注销操作必须随后取消设置此标志,因此他们将被允许在其他地方再次登录。

【讨论】:

我编辑了我的原始帖子。我遗漏了我正在采取的额外步骤。登录到第二个浏览器后,我正在使用 Fiddler 重新向第一个浏览器发出请求,并且每次都重定向到我的登录页面。如果我将 validateInterval 更改为零以外的任何值,我就可以进行多次身份验证。 同样,这段代码与您要实现的目标无关。将验证间隔设置为零实际上会完全杀死登录的能力,因为所有身份验证都会立即无效。您不会阻止多重身份验证;您正在阻止 any 身份验证,其副作用是不允许多个身份验证(即 0 永远不会大于 1)。 我想我混淆了这个问题。我目前正在测试环境中运行此设置,并且在进行身份验证或保持身份验证时没有问题。只有当我更改密码时,我才会立即注销。我现在看到 UserManager 方法 ChangePasswordAsync 正在生成一个新的安全标记 (jamessturtevant.com/posts/…)。再加上验证间隔为零,我被踢了出去。我想也许我可以阻止这种情况,但它似乎是内置的。感谢您的帮助。

以上是关于如何在不影响密码更改行为的情况下正确防止 ASP.NET Identity 2.2.1 中的多个活动会话?的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET Identity 重置密码

如何在不影响背景的情况下更改网页内容?

如何防止 SwiftUI clipShape 影响子视图

如何在不影响设备音量的情况下使用 MPMusicPlayerController 更改音量

如何在不影响现有列宽的情况下更改列数据类型

如何在不影响未分阶段更改的情况下丢弃 git 中的分阶段更改 [重复]