Configure ASP.NET Core Identity
ASP.NET Core Identity uses default values for settings such as password policy, lockout, and cookie configuration. These settings can be overridden at application startup.
Identity options
The IdentityOptions class represents the options that can be used to configure the Identity system. IdentityOptions must be set after calling AddIdentity or AddDefaultIdentity.
Claims Identity
IdentityOptions.ClaimsIdentity specifies the ClaimsIdentityOptions with the properties shown in the following table.
Property | Description | Default |
---|---|---|
RoleClaimType | Gets or sets the claim type used for a role claim. | ClaimTypes.Role |
SecurityStampClaimType | Gets or sets the claim type used for the security stamp claim. | AspNet.Identity.SecurityStamp |
UserIdClaimType | Gets or sets the claim type used for the user identifier claim. | ClaimTypes.NameIdentifier |
UserNameClaimType | Gets or sets the claim type used for the user name claim. | ClaimTypes.Name |
Lockout
Lockout is set in the PasswordSignInAsync method:
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
returnUrl ??= Url.Content("~/");
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
if (ModelState.IsValid)
{
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, set lockoutOnFailure: true
var result = await _signInManager.PasswordSignInAsync(Input.Email,
Input.Password, Input.RememberMe,
lockoutOnFailure: false);
if (result.Succeeded)
{
_logger.LogInformation("User logged in.");
return LocalRedirect(returnUrl);
}
if (result.RequiresTwoFactor)
{
return RedirectToPage("./LoginWith2fa", new { ReturnUrl = returnUrl, RememberMe = Input.RememberMe });
}
if (result.IsLockedOut)
{
_logger.LogWarning("User account locked out.");
return RedirectToPage("./Lockout");
}
else
{
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return Page();
}
}
// If we got this far, something failed, redisplay form
return Page();
}
The preceding code is based on the Login
Identity template.
Lockout options are set in Program.cs
:
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using RPauth.Data;
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddDefaultIdentity<IdentityUser>(options =>
options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddRazorPages();
builder.Services.Configure<IdentityOptions>(options =>
{
// Default Lockout settings.
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
options.Lockout.MaxFailedAccessAttempts = 5;
options.Lockout.AllowedForNewUsers = true;
});
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseMigrationsEndPoint();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
The preceding code sets the IdentityOptions LockoutOptions with default values.
A successful authentication resets the failed access attempts count and resets the clock.
IdentityOptions.Lockout specifies the LockoutOptions with the properties shown in the table.
Property | Description | Default |
---|---|---|
AllowedForNewUsers | Determines if a new user can be locked out. | true |
DefaultLockoutTimeSpan | The amount of time a user is locked out when a lockout occurs. | 5 minutes |
MaxFailedAccessAttempts | The number of failed access attempts until a user is locked out, if lockout is enabled. | 5 |
Password
By default, Identity requires that passwords contain an uppercase character, lowercase character, a digit, and a non-alphanumeric character. Passwords must be at least six characters long.
Passwords are configured with:
- PasswordOptions in
Program.cs
. [StringLength]
attributes ofPassword
properties if Identity is scaffolded into the app.InputModel
Password
properties are found in the following files:Areas/Identity/Pages/Account/Register.cshtml.cs
Areas/Identity/Pages/Account/ResetPassword.cshtml.cs
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using RPauth.Data;
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddDefaultIdentity<IdentityUser>(options =>
options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddRazorPages();
builder.Services.Configure<IdentityOptions>(options =>
{
// Default Password settings.
options.Password.RequireDigit = true;
options.Password.RequireLowercase = true;
options.Password.RequireNonAlphanumeric = true;
options.Password.RequireUppercase = true;
options.Password.RequiredLength = 6;
options.Password.RequiredUniqueChars = 1;
});
var app = builder.Build();
// Remaining code removed for brevity.
IdentityOptions.Password specifies the PasswordOptions with the properties shown in the table.
Property | Description | Default |
---|---|---|
RequireDigit | Requires a number between 0-9 in the password. | true |
RequiredLength | The minimum length of the password. | 6 |
RequireLowercase | Requires a lowercase character in the password. | true |
RequireNonAlphanumeric | Requires a non-alphanumeric character in the password. | true |
RequiredUniqueChars | Only applies to ASP.NET Core 2.0 or later. Requires the number of distinct characters in the password. |
1 |
RequireUppercase | Requires an uppercase character in the password. | true |
Sign-in
The following code sets SignIn
settings (to default values):
builder.Services.Configure<IdentityOptions>(options =>
{
// Default SignIn settings.
options.SignIn.RequireConfirmedEmail = false;
options.SignIn.RequireConfirmedPhoneNumber = false;
});
IdentityOptions.SignIn specifies the SignInOptions with the properties shown in the table.
Property | Description | Default |
---|---|---|
RequireConfirmedEmail | Requires a confirmed email to sign in. | false |
RequireConfirmedPhoneNumber | Requires a confirmed phone number to sign in. | false |
Tokens
IdentityOptions.Tokens specifies the TokenOptions with the properties shown in the table.
Property | Description |
---|---|
AuthenticatorTokenProvider | Gets or sets the AuthenticatorTokenProvider used to validate two-factor sign-ins with an authenticator. |
ChangeEmailTokenProvider | Gets or sets the ChangeEmailTokenProvider used to generate tokens used in email change confirmation emails. |
ChangePhoneNumberTokenProvider | Gets or sets the ChangePhoneNumberTokenProvider used to generate tokens used when changing phone numbers. |
EmailConfirmationTokenProvider | Gets or sets the token provider used to generate tokens used in account confirmation emails. |
PasswordResetTokenProvider | Gets or sets the IUserTwoFactorTokenProvider<TUser> used to generate tokens used in password reset emails. |
ProviderMap | Used to construct a User Token Provider with the key used as the provider's name. |
User
builder.Services.Configure<IdentityOptions>(options =>
{
// Default User settings.
options.User.AllowedUserNameCharacters =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
options.User.RequireUniqueEmail = false;
});
IdentityOptions.User specifies the UserOptions with the properties shown in the table.
Property | Description | Default |
---|---|---|
AllowedUserNameCharacters | Allowed characters in the username. | abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 -._@+ |
RequireUniqueEmail | Requires each user to have a unique email. | false |
Cookie settings
Configure the app's cookie in Program.cs
. ConfigureApplicationCookie must be called after calling AddIdentity
or AddDefaultIdentity
.
builder.Services.ConfigureApplicationCookie(options =>
{
options.AccessDeniedPath = "/Identity/Account/AccessDenied";
options.Cookie.Name = "YourAppCookieName";
options.Cookie.HttpOnly = true;
options.ExpireTimeSpan = TimeSpan.FromMinutes(60);
options.LoginPath = "/Identity/Account/Login";
// ReturnUrlParameter requires
//using Microsoft.AspNetCore.Authentication.Cookies;
options.ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter;
options.SlidingExpiration = true;
});
For more information, see CookieAuthenticationOptions.
Password Hasher options
PasswordHasherOptions gets and sets options for password hashing.
Option | Description |
---|---|
CompatibilityMode | The compatibility mode used when hashing new passwords. Defaults to IdentityV3. The first byte of a hashed password, called a format marker, specifies the version of the hashing algorithm used to hash the password. When verifying a password against a hash, the VerifyHashedPassword method selects the correct algorithm based on the first byte. A client is able to authenticate regardless of which version of the algorithm was used to hash the password. Setting the compatibility mode affects the hashing of new passwords. |
IterationCount | The number of iterations used when hashing passwords using PBKDF2. This value is only used when the CompatibilityMode is set to IdentityV3. The value must be a positive integer and defaults to 100000 . |
In the following example, the IterationCount is set to 12000
in Program.cs
:
// using Microsoft.AspNetCore.Identity;
builder.Services.Configure<PasswordHasherOptions>(option =>
{
option.IterationCount = 12000;
});
Globally require all users to be authenticated
For information on how to globally require all users to be authenticated, see Require authenticated users.
ISecurityStampValidator and SignOut everywhere
Apps need to react to events involving security sensitive actions by regenerating the users ClaimsPrincipal. For example, the ClaimsPrincipal
should be regenerated when joining a role, changing the password, or other security sensitive events. Identity uses the ISecurityStampValidator interface to regenerate the ClaimsPrincipal
. The default implementation of Identity registers a SecurityStampValidator with the main application cookie and the two-factor cookie. The validator hooks into the OnValidatePrincipal event of each cookie to call into Identity to verify that the user's security stamp claim is unchanged from what's stored in the cookie. The validator calls in at regular intervals. The call interval is a tradeoff between hitting the datastore too frequently and not often enough. Checking with a long interval results in stale claims. Call userManager.UpdateSecurityStampAsync(user)
to force existing cookies to be invalided the next time they are checked. Most of the Identity UI account and manage pages call userManager.UpdateSecurityStampAsync(user)
after changing the password or adding a login. Apps can call userManager.UpdateSecurityStampAsync(user)
to implement a sign out everywhere action.
Changing the validation interval is shown in the following highlighted code:
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using WebClaimsPrincipal.Data;
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection")
?? throw new InvalidOperationException("'DefaultConnection' not found.");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddDefaultIdentity<IdentityUser>(options =>
options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
// Force Identity's security stamp to be validated every minute.
builder.Services.Configure<SecurityStampValidatorOptions>(o =>
o.ValidationInterval = TimeSpan.FromMinutes(1));
builder.Services.AddRazorPages();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseMigrationsEndPoint();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
ASP.NET Core Identity uses default values for settings such as password policy, lockout, and cookie configuration. These settings can be overridden in the Startup
class.
Identity options
The IdentityOptions class represents the options that can be used to configure the Identity system. IdentityOptions
must be set after calling AddIdentity
or AddDefaultIdentity
.
Claims Identity
IdentityOptions.ClaimsIdentity specifies the ClaimsIdentityOptions with the properties shown in the following table.
Property | Description | Default |
---|---|---|
RoleClaimType | Gets or sets the claim type used for a role claim. | ClaimTypes.Role |
SecurityStampClaimType | Gets or sets the claim type used for the security stamp claim. | AspNet.Identity.SecurityStamp |
UserIdClaimType | Gets or sets the claim type used for the user identifier claim. | ClaimTypes.NameIdentifier |
UserNameClaimType | Gets or sets the claim type used for the user name claim. | ClaimTypes.Name |
Lockout
Lockout is set in the PasswordSignInAsync method:
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
returnUrl = returnUrl ?? Url.Content("~/");
if (ModelState.IsValid)
{
var result = await _signInManager.PasswordSignInAsync(Input.Email,
Input.Password, Input.RememberMe,
lockoutOnFailure: false);
if (result.Succeeded)
{
_logger.LogInformation("User logged in.");
return LocalRedirect(returnUrl);
}
if (result.RequiresTwoFactor)
{
return RedirectToPage("./LoginWith2fa", new { ReturnUrl = returnUrl,
Input.RememberMe });
}
if (result.IsLockedOut)
{
_logger.LogWarning("User account locked out.");
return RedirectToPage("./Lockout");
}
else
{
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return Page();
}
}
// If we got this far, something failed, redisplay form
return Page();
}
The preceding code is based on the Login
Identity template.
Lockout options are set in StartUp.ConfigureServices
:
services.Configure<IdentityOptions>(options =>
{
// Default Lockout settings.
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
options.Lockout.MaxFailedAccessAttempts = 5;
options.Lockout.AllowedForNewUsers = true;
});
The preceding code sets the IdentityOptions LockoutOptions with default values.
A successful authentication resets the failed access attempts count and resets the clock.
IdentityOptions.Lockout specifies the LockoutOptions with the properties shown in the table.
Property | Description | Default |
---|---|---|
AllowedForNewUsers | Determines if a new user can be locked out. | true |
DefaultLockoutTimeSpan | The amount of time a user is locked out when a lockout occurs. | 5 minutes |
MaxFailedAccessAttempts | The number of failed access attempts until a user is locked out, if lockout is enabled. | 5 |
Password
By default, Identity requires that passwords contain an uppercase character, lowercase character, a digit, and a non-alphanumeric character. Passwords must be at least six characters long.
Passwords are configured with:
- PasswordOptions in
Startup.ConfigureServices
. [StringLength]
attributes ofPassword
properties if Identity is scaffolded into the app.InputModel
Password
properties are found in the following files:Areas/Identity/Pages/Account/Register.cshtml.cs
Areas/Identity/Pages/Account/ResetPassword.cshtml.cs
services.Configure<IdentityOptions>(options =>
{
// Default Password settings.
options.Password.RequireDigit = true;
options.Password.RequireLowercase = true;
options.Password.RequireNonAlphanumeric = true;
options.Password.RequireUppercase = true;
options.Password.RequiredLength = 6;
options.Password.RequiredUniqueChars = 1;
});
IdentityOptions.Password specifies the PasswordOptions with the properties shown in the table.
Property | Description | Default |
---|---|---|
RequireDigit | Requires a number between 0-9 in the password. | true |
RequiredLength | The minimum length of the password. | 6 |
RequireLowercase | Requires a lowercase character in the password. | true |
RequireNonAlphanumeric | Requires a non-alphanumeric character in the password. | true |
RequiredUniqueChars | Only applies to ASP.NET Core 2.0 or later. Requires the number of distinct characters in the password. |
1 |
RequireUppercase | Requires an uppercase character in the password. | true |
Sign-in
The following code sets SignIn
settings (to default values):
services.Configure<IdentityOptions>(options =>
{
// Default SignIn settings.
options.SignIn.RequireConfirmedEmail = false;
options.SignIn.RequireConfirmedPhoneNumber = false;
});
IdentityOptions.SignIn specifies the SignInOptions with the properties shown in the table.
Property | Description | Default |
---|---|---|
RequireConfirmedEmail | Requires a confirmed email to sign in. | false |
RequireConfirmedPhoneNumber | Requires a confirmed phone number to sign in. | false |
Tokens
IdentityOptions.Tokens specifies the TokenOptions with the properties shown in the table.
Property | Description |
---|---|
AuthenticatorTokenProvider | Gets or sets the AuthenticatorTokenProvider used to validate two-factor sign-ins with an authenticator. |
ChangeEmailTokenProvider | Gets or sets the ChangeEmailTokenProvider used to generate tokens used in email change confirmation emails. |
ChangePhoneNumberTokenProvider | Gets or sets the ChangePhoneNumberTokenProvider used to generate tokens used when changing phone numbers. |
EmailConfirmationTokenProvider | Gets or sets the token provider used to generate tokens used in account confirmation emails. |
PasswordResetTokenProvider | Gets or sets the IUserTwoFactorTokenProvider<TUser> used to generate tokens used in password reset emails. |
ProviderMap | Used to construct a User Token Provider with the key used as the provider's name. |
User
services.Configure<IdentityOptions>(options =>
{
// Default User settings.
options.User.AllowedUserNameCharacters =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
options.User.RequireUniqueEmail = false;
});
IdentityOptions.User specifies the UserOptions with the properties shown in the table.
Property | Description | Default |
---|---|---|
AllowedUserNameCharacters | Allowed characters in the username. | abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 -._@+ |
RequireUniqueEmail | Requires each user to have a unique email. | false |
Cookie settings
Configure the app's cookie in Startup.ConfigureServices
. ConfigureApplicationCookie must be called after calling AddIdentity
or AddDefaultIdentity
.
services.ConfigureApplicationCookie(options =>
{
options.AccessDeniedPath = "/Identity/Account/AccessDenied";
options.Cookie.Name = "YourAppCookieName";
options.Cookie.HttpOnly = true;
options.ExpireTimeSpan = TimeSpan.FromMinutes(60);
options.LoginPath = "/Identity/Account/Login";
// ReturnUrlParameter requires
//using Microsoft.AspNetCore.Authentication.Cookies;
options.ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter;
options.SlidingExpiration = true;
});
For more information, see CookieAuthenticationOptions.
Password Hasher options
PasswordHasherOptions gets and sets options for password hashing.
Option | Description |
---|---|
CompatibilityMode | The compatibility mode used when hashing new passwords. Defaults to IdentityV3. The first byte of a hashed password, called a format marker, specifies the version of the hashing algorithm used to hash the password. When verifying a password against a hash, the VerifyHashedPassword method selects the correct algorithm based on the first byte. A client is able to authenticate regardless of which version of the algorithm was used to hash the password. Setting the compatibility mode affects the hashing of new passwords. |
IterationCount | The number of iterations used when hashing passwords using PBKDF2. This value is only used when the CompatibilityMode is set to IdentityV3. The value must be a positive integer and defaults to 10000 . |
In the following example, the IterationCount is set to 12000
in Startup.ConfigureServices
:
// using Microsoft.AspNetCore.Identity;
services.Configure<PasswordHasherOptions>(option =>
{
option.IterationCount = 12000;
});
Globally require all users to be authenticated
For information on how to globally require all users to be authenticated, see Require authenticated users.