How override ASP.NET Core Identity's password policy

By default, ASP.NET Core Identity’s password policy require at least one special character, one uppercase letter, one number, …

How can I change this restrictions ?

There is nothing about that in the documentation (https://docs.asp.net/en/latest/security/authentication/identity.html)

I try to override the Identity’s User Manager but I don’t see which method manages the password policy.

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()             };         }     } } 

I add this user manager dependency in startup’s class :

services.AddScoped<ApplicationUserManager>(); 

But when I’m using ApplicationUserManager in controllers, I have the error : An unhandled exception occurred while processing the request.

InvalidOperationException: Unable to resolve service for type ‘Microsoft.EntityFrameworkCore.DbContextOptions`1[SecurityDbContext]’ while attempting to activate ‘ApplicationUserManager’.

EDIT: User’s management works when I use the ASP.NET Core Identity’s default classes, so it’s not a database problem, or something like this

EDIT 2 : I found the solution, you have just to configure Identity in the startup’s class. My answer gives some details.

Add Comment
4 Answer(s)

It’s sooooo simple in the end …

No need to override any class, you have just to configure the identity settings in your startup class, like this :

services.Configure<IdentityOptions>(options => {     options.Password.RequireDigit = false;     options.Password.RequiredLength = 5;     options.Password.RequireLowercase = true;     options.Password.RequireNonLetterOrDigit = true;     options.Password.RequireUppercase = false; }); 

Or you can configure identity when you add it :

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 is definitively good stuff …

Answered on August 31, 2020.
Add Comment

You can modify these rules in IdentityConfig.cs file. The rules are defined in

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,     }; } 
Add Comment

simplest way for developers is

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>(); 

only Password.RequiredLength can not be changed in this way, it still eqiual 6.

Answered on August 31, 2020.
Add Comment

Additional Requirement:

If you feel this password constraint is not enough, You can define your own conditions by inheriting the PasswordValidator class.

Sample implementation :

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());         }     } 

I have override the ValidateAsync method in my class, and inside this method I am implementing my custom password policy.

Very Very Important

  • The first code line within ValidateAsync()

IdentityResult result = await base.ValidateAsync(manager, user, password); :

Validates the password according to the password rules given in the ConfigureServices method of Statup class (the one showed in the old answers for this post)

  • The password validation functionality is defined by the IPasswordValidator interface in the Microsoft.AspNetCore.Identity namespace. So I need to register my ‘CustomPasswordPolicy’ class as the password validator for ‘AppUser’ objects.
    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();  

Offical Github Documentation of PasswordValidator.cs (for better understanding): here

Answered on August 31, 2020.
Add Comment

Your Answer

By posting your answer, you agree to the privacy policy and terms of service.