配置默认MVC应用程序以使用复杂密码

时间:2013-11-22 16:55:01

标签: asp.net-mvc

我正在尝试将默认的MVC应用修改为要求用户名为电子邮件地址,并且还需要复杂的密码。我发现这个优秀的帖子处理要求用户名是电子邮件地址。 http://blachniet.com/2013/11/10/email-addresses-as-user-names-in-asp-net-identity/

我设法要求最小密码长度为4(见下文)。但现在我正在寻找一个更复杂的验证器。 PasswordValidator类似乎是从IIdentityValidator中获取的。关于如何创建这种类型的CustomPasswordValidator的任何想法?假设我们将使用正则表达式模式来匹配复杂性。

public AccountController(UserManager<ApplicationUser> userManager)
{
    UserManager = userManager;

    //from http://blachniet.com/2013/11/10/email-addresses-as-user-names-in-asp-net-identity/
    UserManager.UserValidator = new CustomUserValidator<ApplicationUser>(UserManager);

    UserManager.PasswordValidator = new MinimumLengthValidator(4);
}

1 个答案:

答案 0 :(得分:3)

这是我的解决方案。您应该能够从VS2013中的默认MVC 5 Web应用程序重新创建它。您将收到一些语法错误。添加适当的Using语句并相应地调整名称空间。

修改Web.config中的<appSettings>部分并添加以下键

    <add key="UsernameRegex" value="^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$" />
    <!-- Require username to be an email address -->
    <add key="Simple" value="^[^\s]{{{0},}}$" />
    <!-- Simple, non-blank password -->
    <add key="1Upper1Lower1Number" value="^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{{{0},}}$" />
    <!-- Complex -->
    <add key="1Upper1Lower1Number1Symbol" value="^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^\da-zA-Z]).{{{0},}}$" />
    <!-- More Complex -->
    <add key="PasswordMinLength" value="8" />
    <!-- Min Password length -->
    <add key="PasswordExpression" value="Simple" />    

添加新的类文件

using Microsoft.AspNet.Identity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Web;

namespace MyApp.Classes
{
    public class CustomUserValidator<TUser> : IIdentityValidator<TUser>
        where TUser : Microsoft.AspNet.Identity.IUser
    {
        private readonly Regex EmailRegex;
        private readonly UserManager<TUser> _manager;

        public CustomUserValidator()
        {
        }

        public CustomUserValidator(UserManager<TUser> manager, string complexityExpression)
        {
            _manager = manager;
            EmailRegex = new Regex(complexityExpression, RegexOptions.Compiled | RegexOptions.IgnoreCase);
        }

        public async Task<IdentityResult> ValidateAsync(TUser item)
        {
            var errors = new List<string>();
            if (!EmailRegex.IsMatch(item.UserName))
                errors.Add("Enter a valid email address.");

            if (_manager != null)
            {
                var otherAccount = await _manager.FindByNameAsync(item.UserName);
                if (otherAccount != null && otherAccount.Id != item.Id)
                    errors.Add("Select a different email address. An account has already been created with this email address.");
            }

            return errors.Any()
                ? IdentityResult.Failed(errors.ToArray())
                : IdentityResult.Success;
        }
    }

    public class CustomPasswordValidator<TUser> : IIdentityValidator<string>
    {
        private Regex PasswordRegex;

        public CustomPasswordValidator(string complexityExpression)
        {
            PasswordRegex = new Regex(complexityExpression, RegexOptions.Compiled);
        }

        public async Task<IdentityResult> ValidateAsync(string item)
        {
            return await Task.Factory.StartNew<IdentityResult>(() =>
            {
                var errors = new List<string>();
                if (!PasswordRegex.IsMatch(item))
                    errors.Add("Password is not complex");

                return errors.Any()
                    ? IdentityResult.Failed(errors.ToArray())
                    : IdentityResult.Success;
            });
        }

    }
}

AccountController.cs中使用

替换public AccountController(UserManager<ApplicationUser> userManager)方法
public AccountController(UserManager<ApplicationUser> userManager)
{
    UserManager = userManager;
    string exp = string.Format(ConfigurationManager.AppSettings[ConfigurationManager.AppSettings["PasswordExpression"]], ConfigurationManager.AppSettings["PasswordMinLength"]);
    UserManager.PasswordValidator = new CustomPasswordValidator<ApplicationUser>(exp);
    UserManager.UserValidator = new CustomUserValidator<ApplicationUser>(UserManager, ConfigurationManager.AppSettings["UsernameRegex"]);
}

归功于这个家伙:http://blachniet.com/2013/11/10/email-addresses-as-user-names-in-asp-net-identity/