Modern HTML attributes such as “passwordrules” and “autocomplete” allow you to tell password generators where your set password fields are and how they should generate passwords.
While password complexity rules are not the best approach for security, ASP.NET Core Identity does use them by default. This includes requirements for uppercase and special characters.
In this article, you will learn how you can automatically implement the “perfect” set password field using your existing ASP.NET Identity password policy and a tag helper found in “ScottBrady.IdentityModel”.
ASP.NET Core Identity & password policies
ASP.NET Core Identity comes preconfigured to require uppercase, lowercase, digits, and non-alphanumeric characters. This policy can conflict with some password generators or the user’s particular password generation settings. If you are enforcing password rules server-side, then it is my opinion that they should be communicated client-side before the user submits an invalid password.
passwordrules
in ASP.NET Core Identity
As part of my ScottBrady.IdentityModel helper library, I have created an ASP.NET Core tag helper for new passwords.
This takes the password policy defined in your ASP.NET Identity PasswordOptions
and automatically builds an input element with the correct passwordrules and attributes.
This means that you can write a newpassword
element in your cshtml:
<newpassword asp-for="Password" />
And, when using the default ASP.NET Identity password policy, get the following input
element in your html:
<input class="form-control" id="password" type="password" name="Password" value=""
autocomplete="new-password" autocorrect="off" autocapitalize="off" minlength="6"
passwordrules="minlength: 6; required: lower; required: upper; required: digit; required: special;" >
This element is configured with attributes based on your ASP.NET Core Identity PasswordOptions
:
RequiredLength
sets the minlength password rule and minlength attributeRequireDigit
: sets the required: digit passwordruleRequireLowercase
: sets the required: lower passwordruleRequireUppercase
: sets the required: upper passwordruleRequireNonAlphanumeric
: sets the required: special passwordrule
Try it yourself
See if your password generator is compatible with passwordrules by using this form input:
- Minimum length: 25+ characters
- Requires: digits, uppercase, lowercase, and special characters
If your password generator supports this, then you should see it suggest a password that meets these policies. If it doesn't, then you'll either get one that doesn't or see nothing at all.
Using the newpassword
tag helper for registration
To use this tag helper in your registration or update page, you’ll need to install the helper library from NuGet. This package has a framework dependency on ASP.NET Core.
dotnet add package ScottBrady.IdentityModel.AspNetCore
You can now enable the tag helpers in your views by adding the following line to your _ViewImports.cshtml
file.
@addTagHelper *, ScottBrady.IdentityModel.AspNetCore
You can now update the password fields on your registration or password update forms with the following, where "Password" is a property on your model.
Much like other tag helpers, you can include other attributes in the element, such as class
.
<newpassword asp-for="Password" />
This results in an input field configured with attributes such as “passwordrules”, “minlength”, and “autocomplete”, based on your ASP.NET Core Identity password options.
Optional: Maximum length and maximum consecutive characters rules
You can also add support for the maximum length and maximum consecutive character rules by changing your PasswordOptions
to be of type ScottBrady.IdentityModel.AspNetCore.Identity.ExtendedPasswordOptions
.
services.AddIdentityCore<IdentityUser>(options =>
{
options.Password = new ExtendedPasswordOptions
{
RequiredLength = 15,
RequireDigit = true,
RequireLowercase = true,
RequireUppercase = true,
RequireNonAlphanumeric = true,
// extended options
MaxLength = 64,
MaxConsecutiveChars = 3
};
})
This can then be enforced server-side using the ExtendedPasswordValidator
:
services.AddIdentityCore<IdentityUser>(/* options */)
.AddPasswordValidator<ExtendedPasswordValidator<IdentityUser>>()
The “max-consecutive characters” uses a basic regex to validate consecutive characters. It is overridable if you need to cover edge-cases that this regex misses.
ScottBrady.IdentityModel.AspNetCore
Hopefully, using PasswordOptions
as the single point of password complexity rule configuration will make life simpler for you when someone inevitably expresses an opinion about the rules and asks you to change them.
For a full explanation of the “passwordrules” attribute, check out my other article, “Perfecting the password field with the HTML passwordrules attribute”.
For more helper libraries in “ScottBrady.IdentityModel”, check out its support for JWTs signed with EdDSA and .NET implementations of JWT alternatives such as Branca and PASETO.