ASP.NET MVC 使用 MembershipPasswordAttribute 收紧密码要求

ASP.NET MVC tightening up password requirement using MembershipPasswordAttribute

提问人:Jefferson 提问时间:9/23/2023 最后编辑:marc_sJefferson 更新时间:10/1/2023 访问量:135

问:

我正在努力收紧我网站上的密码,并想看看我是否可以使用 ?我尝试在我的模型中使用下面的代码,但我没有收到任何错误消息。以下是密码要求,我缺少什么吗?MembershipPassword

密码要求:

  • 10 个字符
  • 大写
  • 小写
  • 特殊字符

https://learn.microsoft.com/en-us/dotnet/api/system.web.security.membershippasswordattribute?view=netframework-4.8

[HTML全文]

<input data-val="true" 
       data-val-password="Your password must be 10 characters long and contain at least one symbol (!, @, #, $, %, ^, etc)." 
       data-val-password-min="10" 
       data-val-password-nonalphamin="1" 
       data-val-required="The Password field is required." 
       id="Password" name="Password" 
       style="width: 100%;" type="password" 
       data-role="textbox" aria-disabled="false" 
       class="k-input k-valid" autocomplete="off">

[Required]
[DataType(DataType.Password)]
[Display(Name = "Password")]
[MembershipPassword(
    MinRequiredNonAlphanumericCharacters = 1,
    MinNonAlphanumericCharactersError = "Your password needs to contain at least one symbol (!, @, #, $, %, ^, etc).",
    ErrorMessage = "Your password must be 10 characters long and contain at least one symbol (!, @, #, $, %, ^, etc).",
    MinRequiredPasswordLength = 10
)]
public string Password { get; set; }

[Required]
[DataType(DataType.Password)]
[Display(Name = "Confirm Password")]
[MembershipPassword(
    MinRequiredNonAlphanumericCharacters = 1,
    MinNonAlphanumericCharactersError = "Your password needs to contain at least one symbol (!, @, #, $, %, ^, etc).",
    ErrorMessage = "Your password must be 10 characters long and contain at least one symbol (!, @, #, $, %, ^, etc).",
    MinRequiredPasswordLength = 10
)]
C# ASP.NET-MVC 密码 数据批注

评论


答:

2赞 VonC 9/25/2023 #1

MembershipPasswordAttribute 本身并非设计用于 MVC 模型验证 ASP.NET;它主要针对 ASP.NET Web 窗体。这意味着,在 MVC 应用程序中的模型验证过程中,将直接附加到模型属性不会自动强制实施约束。MembershipPasswordAttribute

应该能够通过创建自定义验证属性来验证密码(灵感来自“基于配置值的 .NET Core 验证属性”)来实现所需的密码约束。

using System.ComponentModel.DataAnnotations;
using System.Text.RegularExpressions;

public class CustomPasswordAttribute : ValidationAttribute
{
    public override bool IsValid(object value)
    {
        if (value == null) return false;

        var password = value.ToString();

        // Check length
        if (password.Length < 10) return false;

        // Check for uppercase, lowercase, numbers and special characters
        if (!Regex.IsMatch(password, @"[A-Z]") || 
            !Regex.IsMatch(password, @"[a-z]") || 
            !Regex.IsMatch(password, @"[0-9]") || 
            !Regex.IsMatch(password, @"[@$!%*?&#]"))
        {
            return false;
        }

        return true;
    }
}

然后,您可以在模型中使用此属性:

[Required]
[DataType(DataType.Password)]
[Display(Name = "Password")]
[CustomPassword(ErrorMessage = "Your password must meet the required criteria.")]
public string Password { get; set; }

该自定义验证属性将强制执行您指定的密码规则。
IsValid 方法包含实际的验证逻辑。


那么 html5 验证呢,这也会添加它吗?

否,C# 中的自定义验证属性不会自动将 HTML5 验证属性添加到表单字段。ASP.NET MVC 中的 HTML5 验证和服务器端验证是两种独立的机制。
此外,如 dotnet/aspnetcore 问题 20717“是否支持 HTML5 验证?”所示,这本身并不受支持。

要在客户端强制执行相同的规则,您需要手动将 HTML5 属性(如)添加到输入字段。例如:pattern

<input id="Password" name="Password" type="password" 
       pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@$!%*?&#]).{10,}" 
       title="Your password must be 10 characters long and contain at least one uppercase letter, one lowercase letter, one number, and one special character."
       required>

此处的属性使用正则表达式来强制执行规则:pattern

  • (?=.*\d):至少一位数字
  • (?=.*[a-z]):至少一个小写字母
  • (?=.*[A-Z]):至少一个大写字母
  • (?=.*[@$!%*?&#]):至少一个特殊字符
  • .{10,}:长度至少为 10 个字符

该属性将显示一个工具提示,以在验证失败时通知用户有关密码规则的信息。title

因此,如果您想要一个健壮且用户友好的系统,则需要同时维护服务器端和客户端验证。

评论

0赞 Jefferson 9/25/2023
那么 html5 验证呢,这也会添加它吗?
0赞 VonC 9/25/2023
@Jefferson我已经编辑了答案以解决您的评论。
1赞 CSharp 10/1/2023 #2

您不能自己构建密码验证类吗?您可以在添加新用户或用户请求更改密码时调用它。希望您将数据库中的密码保存为哈希或加盐哈希。

using System;
using System.Text.RegularExpressions;

public class PasswordValidator
{
    public static bool IsPasswordValid(string password)
    {
        // Check if the password has at least 10 characters
        if (password.Length < 10)
        {
            return false;
        }

        // Check for at least one uppercase letter
        if (!Regex.IsMatch(password, @"[A-Z]"))
        {
            return false;
        }

        // Check for at least one lowercase letter
        if (!Regex.IsMatch(password, @"[a-z]"))
        {
            return false;
        }

        // Check for at least one digit
        if (!Regex.IsMatch(password, @"\d"))
        {
            return false;
        }

        // Check for at least one special character (non-alphanumeric)
        if (!Regex.IsMatch(password, @"[^a-zA-Z0-9]"))
        {
            return false;
        }

        // If all checks pass, the password is valid
        return true;
    }
}