[英]How override ASP.NET Core Identity's password policy
默認情況下,ASP.NET Core Identity 的密碼策略要求至少一個特殊字符,一個大寫字母,一個數字,...
我怎樣才能改變這個限制?
文檔中沒有任何內容( https://docs.asp.net/en/latest/security/authentication/identity.html )
我嘗試覆蓋身份的用戶管理器,但我看不到哪種方法管理密碼策略。
public class ApplicationUserManager : UserManager<ApplicationUser>
{
public ApplicationUserManager(
DbContextOptions<SecurityDbContext> options,
IServiceProvider services,
IHttpContextAccessor contextAccessor,
ILogger<UserManager<ApplicationUser>> logger)
: base(
new UserStore<ApplicationUser>(new SecurityDbContext(contextAccessor)),
new CustomOptions(),
new PasswordHasher<ApplicationUser>(),
new UserValidator<ApplicationUser>[] { new UserValidator<ApplicationUser>() },
new PasswordValidator[] { new PasswordValidator() },
new UpperInvariantLookupNormalizer(),
new IdentityErrorDescriber(),
services,
logger
// , contextAccessor
)
{
}
public class PasswordValidator : IPasswordValidator<ApplicationUser>
{
public Task<IdentityResult> ValidateAsync(UserManager<ApplicationUser> manager, ApplicationUser user, string password)
{
return Task.Run(() =>
{
if (password.Length >= 4) return IdentityResult.Success;
else { return IdentityResult.Failed(new IdentityError { Code = "SHORTPASSWORD", Description = "Password too short" }); }
});
}
}
public class CustomOptions : IOptions<IdentityOptions>
{
public IdentityOptions Value { get; private set; }
public CustomOptions()
{
Value = new IdentityOptions
{
ClaimsIdentity = new ClaimsIdentityOptions(),
Cookies = new IdentityCookieOptions(),
Lockout = new LockoutOptions(),
Password = null,
User = new UserOptions(),
SignIn = new SignInOptions(),
Tokens = new TokenOptions()
};
}
}
}
我在啟動的 class 中添加了這個用戶管理器依賴項:
services.AddScoped<ApplicationUserManager>();
但是當我在控制器中使用 ApplicationUserManager 時,出現錯誤:處理請求時發生未處理的異常。
InvalidOperationException:在嘗試激活“ApplicationUserManager”時無法解析“Microsoft.EntityFrameworkCore.DbContextOptions`1[SecurityDbContext]”類型的服務。
編輯:當我使用 ASP.NET Core Identity 的默認類時,用戶管理工作,所以這不是數據庫問題,或類似的問題。
最后太簡單了...
無需覆蓋任何類,您只需在啟動類中配置身份設置,如下所示:
services.Configure<IdentityOptions>(options =>
{
options.Password.RequireDigit = false;
options.Password.RequiredLength = 5;
options.Password.RequireLowercase = true;
options.Password.RequireNonLetterOrDigit = true;
options.Password.RequireUppercase = false;
});
或者您可以在添加身份時配置身份:
services.AddIdentity<ApplicationUser, IdentityRole>(options=> {
options.Password.RequireDigit = false;
options.Password.RequiredLength = 4;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireUppercase = false;
options.Password.RequireLowercase = false;
})
.AddEntityFrameworkStores<SecurityDbContext>()
.AddDefaultTokenProviders();
AS.NET Core 絕對是好東西......
您可以在 IdentityConfig.cs 文件中修改這些規則。 規則定義在
public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
{
var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(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 = 5,
RequireNonLetterOrDigit = false,
RequireDigit = true,
RequireLowercase = true,
RequireUppercase = true,
};
}
開發人員最簡單的方法是
services.AddDefaultIdentity<IdentityUser>(options =>
{
options.SignIn.RequireConfirmedAccount = true;
options.Password.RequireDigit = false;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireUppercase = false;
options.Password.RequireLowercase = false;
})
.AddEntityFrameworkStores<ApplicationDbContext>();
只有 Password.RequiredLength 不能以這種方式更改,它仍然等於 6。
附加要求:
如果覺得這個密碼約束不夠,可以通過繼承PasswordValidator類來定義自己的條件。
示例實現:
public class CustomPasswordPolicy : PasswordValidator<AppUser>
{
public override async Task<IdentityResult> ValidateAsync(UserManager<AppUser> manager, AppUser user, string password)
{
IdentityResult result = await base.ValidateAsync(manager, user, password);
List<IdentityError> errors = result.Succeeded ? new List<IdentityError>() : result.Errors.ToList();
if (password.ToLower().Contains(user.UserName.ToLower()))
{
errors.Add(new IdentityError
{
Description = "Password cannot contain username"
});
}
if (password.Contains("123"))
{
errors.Add(new IdentityError
{
Description = "Password cannot contain 123 numeric sequence"
});
}
return errors.Count == 0 ? IdentityResult.Success : IdentityResult.Failed(errors.ToArray());
}
}
我在我的類中覆蓋了 ValidateAsync 方法,在這個方法中我正在實現我的自定義密碼策略。
非常非常重要
IdentityResult result = await base.ValidateAsync(manager, user, password);
:
根據 Statup 類的 ConfigureServices 方法中給出的密碼規則驗證密碼(在這篇文章的舊答案中顯示的規則)
services.AddTransient<IPasswordValidator<AppUser>, CustomPasswordPolicy>();
services.AddDbContext<AppIdentityDbContext>(options => options.UseSqlServer(Configuration["ConnectionStrings:DefaultConnection"]));
services.AddIdentity<AppUser, IdentityRole>(opts =>
{
opts.Password.RequiredLength = 8;
opts.Password.RequireNonAlphanumeric = true;
opts.Password.RequireLowercase = false;
opts.Password.RequireUppercase = true;
opts.Password.RequireDigit = true;
}).AddEntityFrameworkStores<AppIdentityDbContext>().AddDefaultTokenProviders();
PasswordValidator.cs 的官方 Github 文檔(為了更好地理解): 這里
將以下行添加到 startup.cs 的 ConfigureServices 方法
services.Configure<IdentityOptions>(Configuration.GetSection(nameof(IdentityOptions)));
如果需要,您可以使用不同的部分名稱
然后將設置添加到配置中。 您可以在多個配置源中添加多個設置,它們將被合並。 例如,我把它放在我的 appsettings.local.json 文件中。 這個文件被 VCS 忽略,因此我的本地設置永遠不會生效,不像你硬編碼設置並使用 #if debug 或類似的東西。
"IdentityOptions": {
"Password": {
"RequiredLength": 6,
"RequireDigit": false,
"RequiredUniqueChars": 1,
"RequireLowercase": false,
"RequireNonAlphanumeric": false,
"RequireUppercase": false
}
}
這同樣適用於 appsettings.{Environment}.json 或任何其他配置源,因此您可以在開發服務器和實時服務器上進行不同的設置,而無需更改代碼或使用不同的構建配置
我提出這個解決方案:
{
IdentityResult result = await base.ValidateAsync(manager, user, password);
}
這是基於這個 function 驗證將運行 2 次的事實。
第一次用於 PasswordValidator,第二次在 CustomPasswordPolicy 中再次運行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.