From 76d42f09f3e0dd2f2105493eca6b29994aa47706 Mon Sep 17 00:00:00 2001 From: Scott Sauber Date: Tue, 19 Sep 2017 09:44:10 -0500 Subject: [PATCH] Add ASP.NET Core 2 features to Identity Configuration. (#4288) * Add ASP.NET Core 2 features to Identity Configuration. Fixed typo with ASP.NET Core 1 Cookie Name. * Make things more clear and call out the specific options. * Fix wording, spacing, typo on folder name. Display 1.x snippets with more context * Fix typo * Move properties and call out ASP.NET Core 1.x ones. --- .../authentication/identity-configuration.md | 80 ++++++++++++-- .../identity-primary-key-configuration.md | 8 +- .../Controllers/AccountController.cs | 0 .../Data/ApplicationDbContext.cs | 0 .../Models/ApplicationRole.cs | 0 .../Models/ApplicationUser.cs | 0 .../Startup.cs | 2 +- .../Startup.cs | 102 ++++++++++++++++++ 8 files changed, 180 insertions(+), 12 deletions(-) rename aspnetcore/security/authentication/identity/sample/src/{ASPET-IdentityDemo-PrimaryKeysConfig => ASPNET-IdentityDemo-PrimaryKeysConfig}/Controllers/AccountController.cs (100%) rename aspnetcore/security/authentication/identity/sample/src/{ASPET-IdentityDemo-PrimaryKeysConfig => ASPNET-IdentityDemo-PrimaryKeysConfig}/Data/ApplicationDbContext.cs (100%) rename aspnetcore/security/authentication/identity/sample/src/{ASPET-IdentityDemo-PrimaryKeysConfig => ASPNET-IdentityDemo-PrimaryKeysConfig}/Models/ApplicationRole.cs (100%) rename aspnetcore/security/authentication/identity/sample/src/{ASPET-IdentityDemo-PrimaryKeysConfig => ASPNET-IdentityDemo-PrimaryKeysConfig}/Models/ApplicationUser.cs (100%) rename aspnetcore/security/authentication/identity/sample/src/{ASPET-IdentityDemo-PrimaryKeysConfig => ASPNET-IdentityDemo-PrimaryKeysConfig}/Startup.cs (99%) create mode 100644 aspnetcore/security/authentication/identity/sample/src/ASPNETv2-IdentityDemo-Configuration/Startup.cs diff --git a/aspnetcore/security/authentication/identity-configuration.md b/aspnetcore/security/authentication/identity-configuration.md index a42a644dc977..4ebb2bbcb17c 100644 --- a/aspnetcore/security/authentication/identity-configuration.md +++ b/aspnetcore/security/authentication/identity-configuration.md @@ -11,22 +11,88 @@ ms.technology: aspnet ms.prod: asp.net-core uid: security/authentication/identity-configuration --- + # Configure Identity -ASP.NET Core Identity has some default behaviors that you can override easily in your application's startup class. +ASP.NET Core Identity has some default behaviors that you can override easily in your application's `Startup` class. ## Passwords policy -By default, Identity requires that passwords contain an uppercase character, lowercase character, and digits. There are also some other restrictions. If you want to simplify password restrictions, you can do that in the startup class of your application. +By default, Identity requires that passwords contain an uppercase character, lowercase character, a digit, and an alphanumeric character. There are also some other restrictions. If you want to simplify password restrictions, you can do that in the `Startup` class of your application. -[!code-csharp[Main](identity/sample/src/ASPET-IdentityDemo-PrimaryKeysConfig/Startup.cs?highlight=2&range=60-65)] +# [ASP.NET Core 2.x](#tab/aspnetcore2x) -## Application's cookie settings +ASP.NET Core 2.0 added the `RequiredUniqueChars` property. Otherwise, the options are the same from ASP.NET Core 1.x. + +[!code-csharp[Main](identity/sample/src/ASPNETv2-IdentityDemo-Configuration/Startup.cs?range=29-37,50-52)] + +# [ASP.NET Core 1.x](#tab/aspnetcore1x) + +[!code-csharp[Main](identity/sample/src/ASPNET-IdentityDemo-PrimaryKeysConfig/Startup.cs?range=58-65,84)] + +--- -Like the passwords policy, all the settings of the application's cookie can be changed in the startup class. +`IdentityOptions.Password` has the following properties: +* `RequireDigit`: Requires a number between 0-9 in the password. Defaults to true. +* `RequiredLength`: The minimum length of the password. Defaults to 6. +* `RequireNonAlphanumeric`: Requires a non-alphanumeric character in the password. Defaults to true. +* `RequireUppercase`: Requires an upper case character in the password. Defaults to true. +* `RequireLowercase`: Requires a lower case character in the password. Defaults to true. +* `RequiredUniqueChars`: Requires the number of distinct characters in the password. Defaults to 1. -[!code-csharp[Main](identity/sample/src/ASPET-IdentityDemo-PrimaryKeysConfig/Startup.cs?highlight=2&range=72-80)] ## User's lockout -[!code-csharp[Main](identity/sample/src/ASPET-IdentityDemo-PrimaryKeysConfig/Startup.cs?highlight=2&range=67-70)] +[!code-csharp[Main](identity/sample/src/ASPNETv2-IdentityDemo-Configuration/Startup.cs?range=29-30,39-42,50-52)] + +`IdentityOptions.Lockout` has the following properties: +* `DefaultLockoutTimeSpan`: The amount of time a user is locked out when a lockout occurs. Defaults to 5 minutes. +* `MaxFailedAccessAttempts`: The number of failed access attempts until a user is locked out, if lockout is enabled. Defaults to 5. +* `AllowedForNewUsers`: Determines if a new user can be locked out. Defaults to true. + + +## Sign in settings + +[!code-csharp[Main](identity/sample/src/ASPNETv2-IdentityDemo-Configuration/Startup.cs?range=29-30,44-46,50-52)] + +`IdentityOptions.SignIn` has the following properties: +* `RequireConfirmedEmail`: Requires a confirmed email to sign in. Defaults to false. +* `RequireConfirmedPhoneNumber`: Requires a confirmed phone number to sign in. Defaults to false. + + +## User validation settings + +[!code-csharp[Main](identity/sample/src/ASPNETv2-IdentityDemo-Configuration/Startup.cs?range=29-30,48-52)] + +`IdentityOptions.User` has the following properties: +* `RequireUniqueEmail`: Requires each User to have a unique email. Defaults to false. +* `AllowedUserNameCharacters`: Allowed characters in the username. Defaults to abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+. + +## Application's cookie settings + +Like the passwords policy, all the settings of the application's cookie can be changed in the `Startup` class. + +# [ASP.NET Core 2.x](#tab/aspnetcore2x) + +Under `ConfigureServices` in the `Startup` class, you can configure the application's cookie. + +[!code-csharp[Main](identity/sample/src/ASPNETv2-IdentityDemo-Configuration/Startup.cs?name=snippet_configurecookie)] + +# [ASP.NET Core 1.x](#tab/aspnetcore1x) + +[!code-csharp[Main](identity/sample/src/ASPNET-IdentityDemo-PrimaryKeysConfig/Startup.cs?range=58-59,72-80,84)] + +--- + +`CookieAuthenticationOptions` has the following properties: +* `Cookie.Name`: The name of the cookie. Defaults to .AspNetCore.Cookies. +* `Cookie.HttpOnly`: When true, the cookie is not accessible from client-side scripts. Defaults to true. +* `ExpireTimeSpan`: Controls how much time the authentication ticket stored in the cookie will remain valid from the point it is created. Defaults to 14 days. +* `LoginPath`: When a user is unauthorized, they will be redirected to this path to login. Defaults to /Account/Login. +* `LogoutPath`: When a user is logged out, they will be redirected to this path. Defaults to /Account/Logout. +* `AccessDeniedPath`: When a user fails an authorization check, they will be redirected to this path. Defaults to /Account/AccessDenied. +* `SlidingExpiration`: When true, a new cookie will be issued with a new expiration time when the current cookie is more than halfway through the expiration window. Defaults to true. +* `ReturnUrlParameter`: The ReturnUrlParameter determines the name of the query string parameter which is appended by the middleware when a 401 Unauthorized status code is changed to a 302 redirect onto the login path. +* `AuthenticationScheme`: This is only relevant for ASP.NET Core 1.x. The logical name for a particular authentication scheme. +* `AutomaticAuthenticate`: This flag is only relevant for ASP.NET Core 1.x. When true, cookie authentication should run on every request and attempt to validate and reconstruct any serialized principal it created. + diff --git a/aspnetcore/security/authentication/identity-primary-key-configuration.md b/aspnetcore/security/authentication/identity-primary-key-configuration.md index d11e1afedf69..1fa11f8144df 100644 --- a/aspnetcore/security/authentication/identity-primary-key-configuration.md +++ b/aspnetcore/security/authentication/identity-primary-key-configuration.md @@ -10,14 +10,14 @@ ASP.NET Core Identity allows you to easily configure the data type you want for 1. The first step is to implement the Identity's model, and override the string type with the data type you want. - [!code-csharp[Main](identity/sample/src/ASPET-IdentityDemo-PrimaryKeysConfig/Models/ApplicationUser.cs?highlight=4-6&range=7-13)] + [!code-csharp[Main](identity/sample/src/ASPNET-IdentityDemo-PrimaryKeysConfig/Models/ApplicationUser.cs?highlight=4-6&range=7-13)] - [!code-csharp[Main](identity/sample/src/ASPET-IdentityDemo-PrimaryKeysConfig/Models/ApplicationRole.cs?highlight=3-5&range=7-12)] + [!code-csharp[Main](identity/sample/src/ASPNET-IdentityDemo-PrimaryKeysConfig/Models/ApplicationRole.cs?highlight=3-5&range=7-12)] 2. Implement the database context of Identity with your models and the data type you want for primary keys - [!code-csharp[Main](identity/sample/src/ASPET-IdentityDemo-PrimaryKeysConfig/Data/ApplicationDbContext.cs?highlight=3&range=9-26)] + [!code-csharp[Main](identity/sample/src/ASPNET-IdentityDemo-PrimaryKeysConfig/Data/ApplicationDbContext.cs?highlight=3&range=9-26)] 3. Use your models and the data type you want for primary keys when you declare the identity service in your application's startup class - [!code-csharp[Main](identity/sample/src/ASPET-IdentityDemo-PrimaryKeysConfig/Startup.cs?highlight=9-11&range=39-79)] + [!code-csharp[Main](identity/sample/src/ASPNET-IdentityDemo-PrimaryKeysConfig/Startup.cs?highlight=9-11&range=39-79)] diff --git a/aspnetcore/security/authentication/identity/sample/src/ASPET-IdentityDemo-PrimaryKeysConfig/Controllers/AccountController.cs b/aspnetcore/security/authentication/identity/sample/src/ASPNET-IdentityDemo-PrimaryKeysConfig/Controllers/AccountController.cs similarity index 100% rename from aspnetcore/security/authentication/identity/sample/src/ASPET-IdentityDemo-PrimaryKeysConfig/Controllers/AccountController.cs rename to aspnetcore/security/authentication/identity/sample/src/ASPNET-IdentityDemo-PrimaryKeysConfig/Controllers/AccountController.cs diff --git a/aspnetcore/security/authentication/identity/sample/src/ASPET-IdentityDemo-PrimaryKeysConfig/Data/ApplicationDbContext.cs b/aspnetcore/security/authentication/identity/sample/src/ASPNET-IdentityDemo-PrimaryKeysConfig/Data/ApplicationDbContext.cs similarity index 100% rename from aspnetcore/security/authentication/identity/sample/src/ASPET-IdentityDemo-PrimaryKeysConfig/Data/ApplicationDbContext.cs rename to aspnetcore/security/authentication/identity/sample/src/ASPNET-IdentityDemo-PrimaryKeysConfig/Data/ApplicationDbContext.cs diff --git a/aspnetcore/security/authentication/identity/sample/src/ASPET-IdentityDemo-PrimaryKeysConfig/Models/ApplicationRole.cs b/aspnetcore/security/authentication/identity/sample/src/ASPNET-IdentityDemo-PrimaryKeysConfig/Models/ApplicationRole.cs similarity index 100% rename from aspnetcore/security/authentication/identity/sample/src/ASPET-IdentityDemo-PrimaryKeysConfig/Models/ApplicationRole.cs rename to aspnetcore/security/authentication/identity/sample/src/ASPNET-IdentityDemo-PrimaryKeysConfig/Models/ApplicationRole.cs diff --git a/aspnetcore/security/authentication/identity/sample/src/ASPET-IdentityDemo-PrimaryKeysConfig/Models/ApplicationUser.cs b/aspnetcore/security/authentication/identity/sample/src/ASPNET-IdentityDemo-PrimaryKeysConfig/Models/ApplicationUser.cs similarity index 100% rename from aspnetcore/security/authentication/identity/sample/src/ASPET-IdentityDemo-PrimaryKeysConfig/Models/ApplicationUser.cs rename to aspnetcore/security/authentication/identity/sample/src/ASPNET-IdentityDemo-PrimaryKeysConfig/Models/ApplicationUser.cs diff --git a/aspnetcore/security/authentication/identity/sample/src/ASPET-IdentityDemo-PrimaryKeysConfig/Startup.cs b/aspnetcore/security/authentication/identity/sample/src/ASPNET-IdentityDemo-PrimaryKeysConfig/Startup.cs similarity index 99% rename from aspnetcore/security/authentication/identity/sample/src/ASPET-IdentityDemo-PrimaryKeysConfig/Startup.cs rename to aspnetcore/security/authentication/identity/sample/src/ASPNET-IdentityDemo-PrimaryKeysConfig/Startup.cs index c7a7618b9229..e505f6a97088 100644 --- a/aspnetcore/security/authentication/identity/sample/src/ASPET-IdentityDemo-PrimaryKeysConfig/Startup.cs +++ b/aspnetcore/security/authentication/identity/sample/src/ASPNET-IdentityDemo-PrimaryKeysConfig/Startup.cs @@ -70,7 +70,7 @@ public void ConfigureServices(IServiceCollection services) options.Lockout.AllowedForNewUsers = true; // Cookie settings - options.Cookies.ApplicationCookie.CookieName = "YouAppCookieName"; + options.Cookies.ApplicationCookie.CookieName = "YourAppCookieName"; options.Cookies.ApplicationCookie.ExpireTimeSpan = TimeSpan.FromDays(150); options.Cookies.ApplicationCookie.LoginPath = "/Account/LogIn"; options.Cookies.ApplicationCookie.LogoutPath = "/Account/LogOff"; diff --git a/aspnetcore/security/authentication/identity/sample/src/ASPNETv2-IdentityDemo-Configuration/Startup.cs b/aspnetcore/security/authentication/identity/sample/src/ASPNETv2-IdentityDemo-Configuration/Startup.cs new file mode 100644 index 000000000000..fa3d9bc6d571 --- /dev/null +++ b/aspnetcore/security/authentication/identity/sample/src/ASPNETv2-IdentityDemo-Configuration/Startup.cs @@ -0,0 +1,102 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Identity; +using Microsoft.EntityFrameworkCore; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using WebApplication5.Data; +using WebApplication5.Models; +using WebApplication5.Services; + +namespace WebApplication5 +{ + public class Startup + { + public Startup(IConfiguration configuration) + { + Configuration = configuration; + } + + public IConfiguration Configuration { get; } + + #region snippet_configureservices + // This method gets called by the runtime. Use this method to add services to the container. + public void ConfigureServices(IServiceCollection services) + { + services.AddDbContext(options => + options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); + + services.AddIdentity(options => + { + // Password settings + options.Password.RequireDigit = true; + options.Password.RequiredLength = 8; + options.Password.RequireNonAlphanumeric = true; + options.Password.RequireUppercase = true; + options.Password.RequireLowercase = true; + options.Password.RequiredUniqueChars = 2; + + // Lockout settings + options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5); + options.Lockout.MaxFailedAccessAttempts = 5; + options.Lockout.AllowedForNewUsers = true; + + // Signin settings + options.SignIn.RequireConfirmedEmail = true; + options.SignIn.RequireConfirmedPhoneNumber = false; + + // User settings + options.User.RequireUniqueEmail = true; + }) + .AddEntityFrameworkStores() + .AddDefaultTokenProviders(); + + #region snippet_ConfigureCookie + services.ConfigureApplicationCookie(options => + { + options.Cookie.Name = "YourAppCookieName"; + options.Cookie.HttpOnly = true; + options.ExpireTimeSpan = TimeSpan.FromMinutes(60); + options.LoginPath = "/Account/Login"; + options.LogoutPath = "/Account/Logout"; + options.AccessDeniedPath = "/Account/AccessDenied"; + options.SlidingExpiration = true; + }); + #endregion + + // Add application services. + services.AddTransient(); + + services.AddMvc(); + } + #endregion + + #region snippet_configure + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IHostingEnvironment env) + { + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + app.UseBrowserLink(); + app.UseDatabaseErrorPage(); + } + else + { + app.UseExceptionHandler("/Home/Error"); + } + + app.UseStaticFiles(); + + app.UseAuthentication(); + + app.UseMvc(routes => + { + routes.MapRoute( + name: "default", + template: "{controller=Home}/{action=Index}/{id?}"); + }); + } + #endregion + } +}