【问题标题】:Require stronger password for some users based on roles根据角色要求某些用户使用更强的密码
【发布时间】:2012-03-13 22:08:57
【问题描述】:

我有一个 MVC 3 应用程序。关于安全主要有两个区域。第一个主要是防止公共访问,但不是真正的敏感信息。密码强度可能很弱,因为也没有太大的危害。

第二区域(区域)受到限制。用户必须申请访问。如果用户获得访问权限,它将获得某个角色。因此,每个控制器方法都会根据该角色对用户进行自动化。

我希望这些用户在下次登录时必须将密码更改为强密码,然后才能进一步访问受限内容。

示例:

用户 A 申请访问。 授予访问权限。密码策略 只要该用户具有访问权限,该用户就会被更改。他们一定 下次登录时更改密码,并且无法改回 只要他们具有该角色,就可以使用较弱的密码。

有没有使用 ASP.NET 实现此功能的安全方法?

更新

我实际上使用了 Chris 提出的解决方案并且它有效,但是为了处理密码本身的验证,我实际上也从 Micah 提出的解决方案中获得了一些灵感。然而,事实证明,重写 MembershipProvider.OnValidatingPassword 确实意味着还必须实现 10 多个我真的不需要解决这个问题的抽象方法。

在我看来,一个更好的解决方案是连接到 Membership.ValidatingPassword 事件。我在 App_Start 中执行此操作,然后在事件处理程序中实现自己的密码验证,这解决了我的问题。

只是为了与您分享解决方案,我在这里介绍它,与 Chris 解决方案一起解决了我的问题,并希望也适用于其他人:

    void App_Start()
    {
        //To do custom validation on certain passwords set new event handler
        Membership.ValidatingPassword += Membership_ValidatingPassword;
    }

private void Membership_ValidatingPassword(object sender, ValidatePasswordEventArgs e)
    {
        //If the user is a new user, we let registration happen without strong password
        if (e.IsNewUser) return;


        MembershipUser membershipUser = Membership.GetUser(e.UserName);
        Guid userId = Guid.Parse(membershipUser.ProviderUserKey.ToString());

        //First check if the pwd is strong enough to be flagged, if so we flag it
        //using regex to validate the password (20 char, 2 uppercase so on)
        if (MyValidationClass.IsStrongPassword(e.Password, 20, 2, 4, 1))
        {
            //if the user does not already have a flag we set one
            MyValidationClass.SetStrongPasswordFlag(userId);
        }
        else
        {
            //If the user needs strong pwd, we cancel the operation and throw exception
            if (MyValidationClass.NeedsStrongPassword(e.UserName))
            {
                e.FailureInformation =
                    new MembershipPasswordException("Password does not satisfy reqirements!");
                e.Cancel = true;
            }
            else
            {
                MyValidationClass.RemoveStrongPasswordFlag(userId);
            }
        }
    }

【问题讨论】:

  • 您是否曾经在 .NET 中阅读或搜索过有关 Membership and Roles 的任何内容?
  • 如何在角色设置之前请求强密码?现在在更改密码时,您可以通过编程方式执行此操作,但之前不行。
  • @belexandre 是的,我已经阅读了很多关于它的内容,但我还没有看到有关此的信息。我已经对上述问题进行了搜索,但没有找到除基于角色的身份验证之外的信息。这不是我的问题,问题是您可能对您认为机密的内容有非常强的密码要求,但对于其他内容来说是正常的强密码甚至弱密码。虽然我没有看过所有的视频。你的意思是上面的视频链接里有这方面的信息?
  • @Aristos 如果我理解正确:当您申请时,管理员用户会为您的用户设置角色。然后你得到那个角色。下次您获得授权(通过登录或尝试访问受限内容)时,您应该被重定向以升级您的密码。
  • 您在此处描述的所有这些步骤都必须由您以编程方式完成。它们并非万事俱备。

标签: asp.net asp.net-mvc-3 security asp.net-membership authorization


【解决方案1】:

您可以编写自己的授权属性来适应两者。您只需在应用程序的相关部分使用它即可:

例如:

public class HasChangedPasswordAttribute : AuthorizeAttribute
{      
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        UserRepository repo = new UserRepository();
        var user = repo.GetCurrentUser();
        bool hasSecurelyChangedPassword = user.HasSecurelyChangedPassword;
        return hasSecurelyChangedPassword;
    }

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        filterContext.Result = new RedirectResult("/Account/ChangePassword");
    }
}

上面将检查用户是否安全地更改了密码。如果不是,它会将他们重定向到一个新页面,在该页面中更改他们的密码。一旦他们更改它,将标志设置为已更改。

然后你可以像这样使用它:

[HasChangedPassword]
[Authorize(Roles="SuperRole")]
public ActionResult MySecureAction()
{
 ...
}

您显然可以将这两个属性整合为一个,但为了显示上面的示例,它们是分开的。

【讨论】:

  • 嗯,这让我明白了一些事情。我已经为整个站点设置了一个全局过滤器,用于基本授权。如果我添加了检查用户角色的逻辑并且它处于特定角色中,则应用某些规则 - 与上面相同。 ASP.NET 成员资格中是否有任何功能可以检查密码强度。它不是以纯文本形式存储的,因此实际获取用户密码并不容易。
  • 不幸的是,一旦设置好就无法获取它,但是如果您强制用户更改密码(如上所示),您可以在他们提交时检查。如果用户已安全设置,则在数据库中存储一个标志。
  • 谢谢,这可能是一种可行的方法。试图考虑安全隐患。我唯一能想到的是,将未加密的标志存储在数据库中可能是一个问题......另一方面,没有人可以更改该标志......我必须在这方面做一些工作,谢谢。跨度>
  • 我现在已经为此制定了一个解决方案,并且它在我的测试中按计划工作。所以谢谢,这使我朝着正确的方向前进。但是,您是否认为随着用户表的增长,每次请求都访问数据库会对性能产生很大影响?
【解决方案2】:

【讨论】:

  • 您需要源代码来创建新的提供程序还是足以覆盖 OnValidatePassword?
  • 您应该能够从 MembershipProvider 继承并覆盖 OnValidatingPassword。我在想你必须使用给定的那个。再看看可能不是这样的
  • 我将不得不对此进行调查,但对于未来的维护,覆盖方法可能比构建自定义提供程序更好......
【解决方案3】:

当您的用户尝试输入新密码时,可能更简单的方法是在客户端检查密码强度。查看list 了解一些使用 JQuery 的示例。

关于升级和重置密码的事务,这是您的代码可以处理的事情,即用户表中的一个标志,将用户重定向到新的注册页面。但是当他们设置密码(并且可能与适当的强度匹配)后,就可以提交了......

【讨论】:

  • 出于安全原因,应在服务器端验证密码复杂性
  • 我认为使用 jQuery 很容易被绕过。它必须以某种方式在服务器端完成,并且 jQuery 作为帮助来查看它是否符合要求。
猜你喜欢
  • 2017-04-20
  • 1970-01-01
  • 2018-09-24
  • 1970-01-01
  • 2018-10-11
  • 1970-01-01
  • 2020-07-24
  • 2020-08-27
  • 2011-07-10
相关资源
最近更新 更多