我在我的应用程序中管理不同的客户,并且所有客户都在使用相同的mvc应用程序。但是我需要根据客户更改密码验证逻辑。
我在IdentityConfig.cs创建方法中创建了默认密码策略,如下所示:
public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
{
var manager = new ApplicationUserManager(context.Get<ApplicationDbContext>());
// Configure validation logic for usernames
manager.UserValidator = new UserValidator<ApplicationUser>(manager)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = true
};
// Configure validation logic for passwords
manager.PasswordValidator = new PasswordValidator
{
RequiredLength = 6,
RequireNonLetterOrDigit = true,
RequireDigit = true,
RequireLowercase = true,
RequireUppercase = true,
};
// Configure user lockout defaults
manager.UserLockoutEnabledByDefault = true;
manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5);
manager.MaxFailedAccessAttemptsBeforeLockout = 5;
return manager;
}
但是我需要管理特定于客户的PasswordValidator。我正在从子域中获取当前客户,我的意思是如果我的URL是http://example.com/customer1,那么我知道这是customer1并从数据库中获取密码策略设置。我将这些设置放入Session变量中。我可以在IdentityConfig Create方法中使用会话变量,还是在创建会话后如何覆盖PasswordValidator属性?
答案 0 :(得分:1)
您可以通过扩展IIdentityValidator
来创建自己的自定义密码验证器:
// your first validator logic
public class CustomPasswordValidator1: IIdentityValidator<string>
{
public CustomPasswordValidator1(int length)
{
RequiredLength = length;
}
public int RequiredLength { get; set; }
public Task<IdentityResult> ValidateAsync(string password)
{
// write your own validation logic here
if (string.IsNullOrEmpty(password) || password.Length < RequiredLength)
{
return Task.FromResult(IdentityResult.Failed("bad password"));
}
// good password
return Task.FromResult(IdentityResult.Success);
}
}
// your second validator logic
public class CustomPasswordValidator2: IIdentityValidator<string>
{
public CustomPasswordValidator2(int length)
{
RequiredLength = length;
}
public int RequiredLength { get; set; }
public Task<IdentityResult> ValidateAsync(string password)
{
// write some other validation logic
}
}
See here,了解有关如何扩展IIdentityValidator
现在,您拥有CustomPasswordValidator1
和CustomPasswordValidator2
,可以更改ApplicationUserManager
代码,并使用正确的验证器逻辑:
public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
{
var manager = new ApplicationUserManager(new CustomUserStore(context.Get<ApplicationDbContext>()));
manager.UserValidator = new UserValidator<ApplicationUser, long>(manager)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = true
};
if (/* some condition */)
{
manager.PasswordValidator = new CustomPasswordValidator1(6 /*min length*/ );
}
else
{
manager.PasswordValidator = new CustomPasswordValidator2(12 /*min length*/);
}
// more code...
答案 1 :(得分:0)
在管理器中定义验证器时遇到了类似的问题。完成后,它们似乎不再可以调整了。
最后,我创建了一个单独的功能,可以在其中获取策略并将其应用于IdentityOpions。之后,我可以使用这些选项创建验证器并将其添加到管理器中。验证程序似乎将选项作为默认值考虑在内,而不是让您即时调整它们。
public class ApplicationUserManager : UserManager<ApplicationUser>
{
internal void SetPolicies(Dictionary<string, string> passwordPolicies)
{ // do stuff in a loop, like getting the policies like this:
Options.Password.RequireDigit = policy.value;
// Then create and add the validator with the new policies in place.
_passwordValidator = new PasswordValidator<ApplicationUser>();
this.PasswordValidators.Add(_passwordValidator);
}
}