From 8c6bb075e59cb1a41ca6670a7be68954e60b93fb Mon Sep 17 00:00:00 2001 From: Scott Addie Date: Tue, 10 Oct 2017 13:34:19 -0500 Subject: [PATCH 01/15] 2.0 update of Limiting identity by scheme doc --- .../authorization/limitingidentitybyscheme.md | 95 ++++++++++++++----- 1 file changed, 73 insertions(+), 22 deletions(-) diff --git a/aspnetcore/security/authorization/limitingidentitybyscheme.md b/aspnetcore/security/authorization/limitingidentitybyscheme.md index 53d034bcaf..8ffa427e9c 100644 --- a/aspnetcore/security/authorization/limitingidentitybyscheme.md +++ b/aspnetcore/security/authorization/limitingidentitybyscheme.md @@ -2,10 +2,10 @@ title: Limiting identity by scheme author: rick-anderson description: -keywords: ASP.NET Core, +keywords: ASP.NET Core,identity,authentication scheme ms.author: riande manager: wpickett -ms.date: 10/14/2016 +ms.date: 10/10/2017 ms.topic: article ms.assetid: d3d6ca1b-b4b5-4bf7-898e-dcd90ec1bf8c ms.technology: aspnet @@ -16,51 +16,102 @@ uid: security/authorization/limitingidentitybyscheme -In some scenarios, such as Single Page Applications it is possible to end up with multiple authentication methods. For example, your application may use cookie-based authentication to log in and bearer authentication for JavaScript requests. In some cases you may have multiple instances of an authentication middleware. For example, two cookie middlewares where one contains a basic identity and one is created when a multi-factor authentication has triggered because the user requested an operation that requires extra security. +In some scenarios, such as Single Page Applications, it's common to use multiple authentication methods. For example, your application may use cookie-based authentication to log in and JWT bearer authentication for JavaScript requests. In some cases, you may have multiple instances of an authentication middleware. For example, two cookie middlewares where one contains a basic identity and one is created when a multi-factor authentication has triggered (because the user requested an operation that requires extra security). -Authentication schemes are named when authentication middleware is configured during authentication, for example +Authentication schemes are named when authentication middleware is configured during authentication. For example: + +# [ASP.NET Core 2.x](#tab/aspnetcore2x) ```csharp -app.UseCookieAuthentication(new CookieAuthenticationOptions() +public void ConfigureServices(IServiceCollection services) { - AuthenticationScheme = "Cookie", - LoginPath = new PathString("/Account/Unauthorized/"), - AccessDeniedPath = new PathString("/Account/Forbidden/"), - AutomaticAuthenticate = false -}); + // Code omitted for brevity -app.UseBearerAuthentication(options => -{ - options.AuthenticationScheme = "Bearer"; - options.AutomaticAuthenticate = false; -}); + services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) + .AddCookie(options => { + options.LoginPath = "/Account/Unauthorized/"; + options.AccessDeniedPath = "/Account/Forbidden/"; + }); + + services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) + .AddJwtBearer(); ``` -In this configuration two authentication middlewares have been added, one for cookies and one for bearer. +In the preceding code, two authentication services have been added: one for cookies and one for bearer. >[!NOTE] ->When adding multiple authentication middleware you should ensure that no middleware is configured to run automatically. You do this by setting the `AutomaticAuthenticate` options property to false. If you fail to do this filtering by scheme will not work. +>When adding multiple authentication middlewares, ensure that no middleware is configured to run automatically. You do this by setting the `AutomaticAuthenticate` options property to false. If you fail to do this, filtering by scheme will not work. + +# [ASP.NET Core 1.x](#tab/aspnetcore1x) + +```csharp +public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) +{ + // Code omitted for brevity + + app.UseCookieAuthentication(new CookieAuthenticationOptions() + { + AuthenticationScheme = "Cookie", + LoginPath = "/Account/Unauthorized/", + AccessDeniedPath = "/Account/Forbidden/", + AutomaticAuthenticate = false + }); + + app.UseJwtBearerAuthentication(new JwtBearerOptions() + { + AuthenticationScheme = "Bearer", + AutomaticAuthenticate = false + }); +``` + +In the preceding code, two authentication middlewares have been added: one for cookies and one for bearer. + +>[!NOTE] +>When adding multiple authentication middlewares, ensure that no middleware is configured to run automatically. You do this by setting the `AutomaticAuthenticate` options property to false. If you fail to do this, filtering by scheme will not work. + +--- ## Selecting the scheme with the Authorize attribute -As no authentication middleware is configured to automatically run and create an identity you must, at the point of authorization choose which middleware will be used. The simplest way to select the middleware you wish to authorize with is to use the `ActiveAuthenticationSchemes` property. This property accepts a comma delimited list of Authentication Schemes to use. For example; +No authentication middleware is configured to automatically run and create an identity. At the point of authorization, you choose which middleware will be used. The simplest way to select the middleware with which you wish to authorize is to use the `ActiveAuthenticationSchemes` property. This property accepts a comma-delimited list of authentication schemes to use. For example: + +# [ASP.NET Core 2.x](#tab/aspnetcore2x) + +```csharp +[Authorize(AuthenticationSchemes = "Cookie,Bearer")] +public class MixedController : Controller +``` + +# [ASP.NET Core 1.x](#tab/aspnetcore1x) ```csharp [Authorize(ActiveAuthenticationSchemes = "Cookie,Bearer")] public class MixedController : Controller ``` -In the example above both the cookie and bearer middlewares will run and have a chance to create and append an identity for the current user. By specifying a single scheme only the specified middleware will run; +--- + +In the example above, both the cookie and bearer middlewares run and have a chance to create and append an identity for the current user. By specifying a single scheme only, the specified middleware runs. + +# [ASP.NET Core 2.x](#tab/aspnetcore2x) + +```csharp +[Authorize(AuthenticationSchemes = "Bearer")] +``` + +# [ASP.NET Core 1.x](#tab/aspnetcore1x) ```csharp [Authorize(ActiveAuthenticationSchemes = "Bearer")] ``` -In this case only the middleware with the Bearer scheme would run, and any cookie based identities would be ignored. +--- + +In this case, only the middleware with the "Bearer" scheme runs. Any cookie-based identities are ignored. ## Selecting the scheme with policies -If you prefer to specify the desired schemes in [policy](policies.md#security-authorization-policies-based) you can set the `AuthenticationSchemes` collection when adding your policy. +If you prefer to specify the desired schemes in [policy](policies.md#security-authorization-policies-based), you can set the `AuthenticationSchemes` collection when adding your policy: ```csharp options.AddPolicy("Over18", policy => @@ -71,4 +122,4 @@ options.AddPolicy("Over18", policy => }); ``` -In this example the Over18 policy will only run against the identity created by the `Bearer` middleware. +In this example, the "Over18" policy only runs against the identity created by the "Bearer" middleware. From 1d087dc6e71e972d75ee46a41a39514104434327 Mon Sep 17 00:00:00 2001 From: Scott Addie Date: Tue, 10 Oct 2017 14:47:05 -0500 Subject: [PATCH 02/15] Update 2.0 code snippet --- .../security/authorization/limitingidentitybyscheme.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/aspnetcore/security/authorization/limitingidentitybyscheme.md b/aspnetcore/security/authorization/limitingidentitybyscheme.md index 8ffa427e9c..cc1c2eb3e9 100644 --- a/aspnetcore/security/authorization/limitingidentitybyscheme.md +++ b/aspnetcore/security/authorization/limitingidentitybyscheme.md @@ -18,7 +18,7 @@ uid: security/authorization/limitingidentitybyscheme In some scenarios, such as Single Page Applications, it's common to use multiple authentication methods. For example, your application may use cookie-based authentication to log in and JWT bearer authentication for JavaScript requests. In some cases, you may have multiple instances of an authentication middleware. For example, two cookie middlewares where one contains a basic identity and one is created when a multi-factor authentication has triggered (because the user requested an operation that requires extra security). -Authentication schemes are named when authentication middleware is configured during authentication. For example: +Authentication schemes are named when authentication middlewares or services are configured during authentication. For example: # [ASP.NET Core 2.x](#tab/aspnetcore2x) @@ -31,16 +31,14 @@ public void ConfigureServices(IServiceCollection services) .AddCookie(options => { options.LoginPath = "/Account/Unauthorized/"; options.AccessDeniedPath = "/Account/Forbidden/"; - }); - - services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) + }) .AddJwtBearer(); ``` In the preceding code, two authentication services have been added: one for cookies and one for bearer. >[!NOTE] ->When adding multiple authentication middlewares, ensure that no middleware is configured to run automatically. You do this by setting the `AutomaticAuthenticate` options property to false. If you fail to do this, filtering by scheme will not work. +>When adding multiple authentication middlewares, ensure that no middleware is configured to run automatically. You do this by setting the `AuthenticationOptions.AutomaticAuthenticate` property to false. If you fail to do this, filtering by scheme will not work. # [ASP.NET Core 1.x](#tab/aspnetcore1x) @@ -67,7 +65,7 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerF In the preceding code, two authentication middlewares have been added: one for cookies and one for bearer. >[!NOTE] ->When adding multiple authentication middlewares, ensure that no middleware is configured to run automatically. You do this by setting the `AutomaticAuthenticate` options property to false. If you fail to do this, filtering by scheme will not work. +>When adding multiple authentication middlewares, ensure that no middleware is configured to run automatically. You do this by setting the `AuthenticationOptions.AutomaticAuthenticate` property to false. If you fail to do this, filtering by scheme will not work. --- From cc85485f9adc5c5e0d792418b97d52f0f3fd50bb Mon Sep 17 00:00:00 2001 From: Scott Addie Date: Wed, 11 Oct 2017 10:44:16 -0500 Subject: [PATCH 03/15] Remove unnecessary anchor --- aspnetcore/security/authentication/cookie.md | 2 +- aspnetcore/security/authorization/limitingidentitybyscheme.md | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/aspnetcore/security/authentication/cookie.md b/aspnetcore/security/authentication/cookie.md index 6175057918..eaa25b6080 100644 --- a/aspnetcore/security/authentication/cookie.md +++ b/aspnetcore/security/authentication/cookie.md @@ -71,7 +71,7 @@ The code snippets above configure some or all of the following options: * `AccessDeniedPath` - This is the relative path to which requests redirect when a user attempts to access a resource but does not pass any [authorization policies](xref:security/authorization/policies#security-authorization-policies-based) for that resource. -* `AuthenticationScheme` - This is a value by which a particular cookie authentication scheme is known. This is useful when there are multiple instances of cookie authentication and you want to [limit authorization to one instance](xref:security/authorization/limitingidentitybyscheme#security-authorization-limiting-by-scheme). +* `AuthenticationScheme` - This is a value by which a particular cookie authentication scheme is known. This is useful when there are multiple instances of cookie authentication and you want to [limit authorization to one instance](xref:security/authorization/limitingidentitybyscheme). * `AutomaticAuthenticate` - This flag is relevant only for ASP.NET Core 1.x. It indicates that the cookie authentication should run on every request and attempt to validate and reconstruct any serialized principal it created. diff --git a/aspnetcore/security/authorization/limitingidentitybyscheme.md b/aspnetcore/security/authorization/limitingidentitybyscheme.md index cc1c2eb3e9..c6b7d96baf 100644 --- a/aspnetcore/security/authorization/limitingidentitybyscheme.md +++ b/aspnetcore/security/authorization/limitingidentitybyscheme.md @@ -14,8 +14,6 @@ uid: security/authorization/limitingidentitybyscheme --- # Limiting identity by scheme - - In some scenarios, such as Single Page Applications, it's common to use multiple authentication methods. For example, your application may use cookie-based authentication to log in and JWT bearer authentication for JavaScript requests. In some cases, you may have multiple instances of an authentication middleware. For example, two cookie middlewares where one contains a basic identity and one is created when a multi-factor authentication has triggered (because the user requested an operation that requires extra security). Authentication schemes are named when authentication middlewares or services are configured during authentication. For example: From 6d03b6651b2356dcdcdf7895070928db162878d0 Mon Sep 17 00:00:00 2001 From: Scott Addie Date: Wed, 11 Oct 2017 11:47:11 -0500 Subject: [PATCH 04/15] Update note for 2.0 --- .../security/authorization/limitingidentitybyscheme.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/aspnetcore/security/authorization/limitingidentitybyscheme.md b/aspnetcore/security/authorization/limitingidentitybyscheme.md index c6b7d96baf..646e500beb 100644 --- a/aspnetcore/security/authorization/limitingidentitybyscheme.md +++ b/aspnetcore/security/authorization/limitingidentitybyscheme.md @@ -1,7 +1,7 @@ --- -title: Limiting identity by scheme +title: Limiting identity by scheme - ASP.NET Core author: rick-anderson -description: +description: This article explains how to limit identity to a specific schema when working with multiple authentication methods. keywords: ASP.NET Core,identity,authentication scheme ms.author: riande manager: wpickett @@ -36,7 +36,7 @@ public void ConfigureServices(IServiceCollection services) In the preceding code, two authentication services have been added: one for cookies and one for bearer. >[!NOTE] ->When adding multiple authentication middlewares, ensure that no middleware is configured to run automatically. You do this by setting the `AuthenticationOptions.AutomaticAuthenticate` property to false. If you fail to do this, filtering by scheme will not work. +>When adding multiple authentication middlewares, ensure that no middleware is configured to run automatically. You do this by supplying an argument, such as `CookieAuthenticationDefaults.AuthenticationScheme`, to the `AddAuthentication` method. If you fail to do this, filtering by scheme will not work. # [ASP.NET Core 1.x](#tab/aspnetcore1x) From 304a6352fe6dd4d2e048dbde0ea37343794b6e75 Mon Sep 17 00:00:00 2001 From: Scott Addie Date: Wed, 11 Oct 2017 13:37:31 -0500 Subject: [PATCH 05/15] Minor edits --- .../authorization/limitingidentitybyscheme.md | 40 ++++++++++--------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/aspnetcore/security/authorization/limitingidentitybyscheme.md b/aspnetcore/security/authorization/limitingidentitybyscheme.md index 646e500beb..ccb53a2647 100644 --- a/aspnetcore/security/authorization/limitingidentitybyscheme.md +++ b/aspnetcore/security/authorization/limitingidentitybyscheme.md @@ -16,10 +16,10 @@ uid: security/authorization/limitingidentitybyscheme In some scenarios, such as Single Page Applications, it's common to use multiple authentication methods. For example, your application may use cookie-based authentication to log in and JWT bearer authentication for JavaScript requests. In some cases, you may have multiple instances of an authentication middleware. For example, two cookie middlewares where one contains a basic identity and one is created when a multi-factor authentication has triggered (because the user requested an operation that requires extra security). -Authentication schemes are named when authentication middlewares or services are configured during authentication. For example: - # [ASP.NET Core 2.x](#tab/aspnetcore2x) +An authentication scheme is named when the authentication service is configured during authentication. For example: + ```csharp public void ConfigureServices(IServiceCollection services) { @@ -40,25 +40,27 @@ In the preceding code, two authentication services have been added: one for cook # [ASP.NET Core 1.x](#tab/aspnetcore1x) -```csharp -public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) -{ - // Code omitted for brevity +Authentication schemes are named when authentication middlewares are configured during authentication. For example: - app.UseCookieAuthentication(new CookieAuthenticationOptions() + ```csharp + public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { - AuthenticationScheme = "Cookie", - LoginPath = "/Account/Unauthorized/", - AccessDeniedPath = "/Account/Forbidden/", - AutomaticAuthenticate = false - }); + // Code omitted for brevity - app.UseJwtBearerAuthentication(new JwtBearerOptions() - { - AuthenticationScheme = "Bearer", - AutomaticAuthenticate = false - }); -``` + app.UseCookieAuthentication(new CookieAuthenticationOptions() + { + AuthenticationScheme = "Cookie", + LoginPath = "/Account/Unauthorized/", + AccessDeniedPath = "/Account/Forbidden/", + AutomaticAuthenticate = false + }); + + app.UseJwtBearerAuthentication(new JwtBearerOptions() + { + AuthenticationScheme = "Bearer", + AutomaticAuthenticate = false + }); + ``` In the preceding code, two authentication middlewares have been added: one for cookies and one for bearer. @@ -93,12 +95,14 @@ In the example above, both the cookie and bearer middlewares run and have a chan ```csharp [Authorize(AuthenticationSchemes = "Bearer")] +public class MixedController : Controller ``` # [ASP.NET Core 1.x](#tab/aspnetcore1x) ```csharp [Authorize(ActiveAuthenticationSchemes = "Bearer")] +public class MixedController : Controller ``` --- From 87c6f7ecce35944813de14d71a4bc005d77c1dfa Mon Sep 17 00:00:00 2001 From: Scott Addie Date: Wed, 11 Oct 2017 13:41:28 -0500 Subject: [PATCH 06/15] Provide more context in last code snippet --- .../authorization/limitingidentitybyscheme.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/aspnetcore/security/authorization/limitingidentitybyscheme.md b/aspnetcore/security/authorization/limitingidentitybyscheme.md index ccb53a2647..10f7574582 100644 --- a/aspnetcore/security/authorization/limitingidentitybyscheme.md +++ b/aspnetcore/security/authorization/limitingidentitybyscheme.md @@ -114,11 +114,14 @@ In this case, only the middleware with the "Bearer" scheme runs. Any cookie-base If you prefer to specify the desired schemes in [policy](policies.md#security-authorization-policies-based), you can set the `AuthenticationSchemes` collection when adding your policy: ```csharp -options.AddPolicy("Over18", policy => +services.AddAuthorization(options => { - policy.AuthenticationSchemes.Add("Bearer"); - policy.RequireAuthenticatedUser(); - policy.Requirements.Add(new Over18Requirement()); + options.AddPolicy("Over18", policy => + { + policy.AuthenticationSchemes.Add("Bearer"); + policy.RequireAuthenticatedUser(); + policy.Requirements.Add(new Over18Requirement()); + }); }); ``` From e0bf5eb48befdb490c5c623a683bf922a5b0bbd2 Mon Sep 17 00:00:00 2001 From: Scott Addie Date: Wed, 11 Oct 2017 13:48:28 -0500 Subject: [PATCH 07/15] Dedent code snippet --- .../authorization/limitingidentitybyscheme.md | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/aspnetcore/security/authorization/limitingidentitybyscheme.md b/aspnetcore/security/authorization/limitingidentitybyscheme.md index 10f7574582..96459091d2 100644 --- a/aspnetcore/security/authorization/limitingidentitybyscheme.md +++ b/aspnetcore/security/authorization/limitingidentitybyscheme.md @@ -42,25 +42,25 @@ In the preceding code, two authentication services have been added: one for cook Authentication schemes are named when authentication middlewares are configured during authentication. For example: - ```csharp - public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) +```csharp +public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) +{ + // Code omitted for brevity + + app.UseCookieAuthentication(new CookieAuthenticationOptions() { - // Code omitted for brevity + AuthenticationScheme = "Cookie", + LoginPath = "/Account/Unauthorized/", + AccessDeniedPath = "/Account/Forbidden/", + AutomaticAuthenticate = false + }); - app.UseCookieAuthentication(new CookieAuthenticationOptions() - { - AuthenticationScheme = "Cookie", - LoginPath = "/Account/Unauthorized/", - AccessDeniedPath = "/Account/Forbidden/", - AutomaticAuthenticate = false - }); - - app.UseJwtBearerAuthentication(new JwtBearerOptions() - { - AuthenticationScheme = "Bearer", - AutomaticAuthenticate = false - }); - ``` + app.UseJwtBearerAuthentication(new JwtBearerOptions() + { + AuthenticationScheme = "Bearer", + AutomaticAuthenticate = false + }); +``` In the preceding code, two authentication middlewares have been added: one for cookies and one for bearer. From 6625b36affc0615d3ad47ea2417595d71ba2fed6 Mon Sep 17 00:00:00 2001 From: Scott Addie Date: Wed, 11 Oct 2017 14:04:07 -0500 Subject: [PATCH 08/15] Convert link to xref style --- aspnetcore/security/authorization/limitingidentitybyscheme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aspnetcore/security/authorization/limitingidentitybyscheme.md b/aspnetcore/security/authorization/limitingidentitybyscheme.md index 96459091d2..d920721153 100644 --- a/aspnetcore/security/authorization/limitingidentitybyscheme.md +++ b/aspnetcore/security/authorization/limitingidentitybyscheme.md @@ -111,7 +111,7 @@ In this case, only the middleware with the "Bearer" scheme runs. Any cookie-base ## Selecting the scheme with policies -If you prefer to specify the desired schemes in [policy](policies.md#security-authorization-policies-based), you can set the `AuthenticationSchemes` collection when adding your policy: +If you prefer to specify the desired schemes in [policy](xref:security/authorization/policies#security-authorization-policies-based), you can set the `AuthenticationSchemes` collection when adding your policy: ```csharp services.AddAuthorization(options => From 134813bf5968589a0199614d084e64b76f2d8eca Mon Sep 17 00:00:00 2001 From: Scott Addie Date: Wed, 11 Oct 2017 15:13:20 -0500 Subject: [PATCH 09/15] React to feedback --- .../authorization/limitingidentitybyscheme.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/aspnetcore/security/authorization/limitingidentitybyscheme.md b/aspnetcore/security/authorization/limitingidentitybyscheme.md index d920721153..46fd0a0c85 100644 --- a/aspnetcore/security/authorization/limitingidentitybyscheme.md +++ b/aspnetcore/security/authorization/limitingidentitybyscheme.md @@ -25,18 +25,21 @@ public void ConfigureServices(IServiceCollection services) { // Code omitted for brevity - services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) + services.AddAuthentication() .AddCookie(options => { options.LoginPath = "/Account/Unauthorized/"; options.AccessDeniedPath = "/Account/Forbidden/"; }) - .AddJwtBearer(); + .AddJwtBearer(options => { + options.Audience = "http://localhost:5001/"; + options.Authority = "http://localhost:5000/"; + }); ``` In the preceding code, two authentication services have been added: one for cookies and one for bearer. >[!NOTE] ->When adding multiple authentication middlewares, ensure that no middleware is configured to run automatically. You do this by supplying an argument, such as `CookieAuthenticationDefaults.AuthenticationScheme`, to the `AddAuthentication` method. If you fail to do this, filtering by scheme will not work. +>When adding multiple authentication middlewares, ensure that no middleware is configured to run automatically. You do this by invoking `AddAuthentication` with no arguments. If you fail to do this, filtering by scheme doesn't work. For example, `AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)` makes cookies run automatically. # [ASP.NET Core 1.x](#tab/aspnetcore1x) @@ -58,20 +61,22 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerF app.UseJwtBearerAuthentication(new JwtBearerOptions() { AuthenticationScheme = "Bearer", - AutomaticAuthenticate = false + AutomaticAuthenticate = false, + Audience = "http://localhost:5001/", + Authority = "http://localhost:5000/" }); ``` In the preceding code, two authentication middlewares have been added: one for cookies and one for bearer. >[!NOTE] ->When adding multiple authentication middlewares, ensure that no middleware is configured to run automatically. You do this by setting the `AuthenticationOptions.AutomaticAuthenticate` property to false. If you fail to do this, filtering by scheme will not work. +>When adding multiple authentication middlewares, ensure that no middleware is configured to run automatically. You do this by setting the `AuthenticationOptions.AutomaticAuthenticate` property to false. If you fail to do this, filtering by scheme doesn't work. --- ## Selecting the scheme with the Authorize attribute -No authentication middleware is configured to automatically run and create an identity. At the point of authorization, you choose which middleware will be used. The simplest way to select the middleware with which you wish to authorize is to use the `ActiveAuthenticationSchemes` property. This property accepts a comma-delimited list of authentication schemes to use. For example: +At the point of authorization, you indicate the middleware to be used. The simplest way to select the middleware with which you wish to authorize is to pass a comma-delimited list of authentication schemes to the `[Authorize]` attribute. The `[Authorize]` attribute specifies the authentication scheme or schemes to use regardless of whether a default is configured. For example: # [ASP.NET Core 2.x](#tab/aspnetcore2x) From a06e47425ea19a2e1d1d977ca7fda9aedfb9e7de Mon Sep 17 00:00:00 2001 From: Rick Anderson Date: Wed, 11 Oct 2017 16:32:14 -1000 Subject: [PATCH 10/15] Update limitingidentitybyscheme.md --- .../authorization/limitingidentitybyscheme.md | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/aspnetcore/security/authorization/limitingidentitybyscheme.md b/aspnetcore/security/authorization/limitingidentitybyscheme.md index 46fd0a0c85..a76e30712b 100644 --- a/aspnetcore/security/authorization/limitingidentitybyscheme.md +++ b/aspnetcore/security/authorization/limitingidentitybyscheme.md @@ -14,7 +14,7 @@ uid: security/authorization/limitingidentitybyscheme --- # Limiting identity by scheme -In some scenarios, such as Single Page Applications, it's common to use multiple authentication methods. For example, your application may use cookie-based authentication to log in and JWT bearer authentication for JavaScript requests. In some cases, you may have multiple instances of an authentication middleware. For example, two cookie middlewares where one contains a basic identity and one is created when a multi-factor authentication has triggered (because the user requested an operation that requires extra security). +In some scenarios, such as Single Page Applications (SPAs), it's common to use multiple authentication methods. For example, the application may use cookie-based authentication to log in and JWT bearer authentication for JavaScript requests. In some cases, the app may have multiple instances of an authentication middleware. For example, two cookie middlewares where one contains a basic identity and one is created when a multi-factor authentication (MFA) has been triggered. MFA may be triggered because the user requested an operation that requires extra security. # [ASP.NET Core 2.x](#tab/aspnetcore2x) @@ -39,7 +39,9 @@ public void ConfigureServices(IServiceCollection services) In the preceding code, two authentication services have been added: one for cookies and one for bearer. >[!NOTE] ->When adding multiple authentication middlewares, ensure that no middleware is configured to run automatically. You do this by invoking `AddAuthentication` with no arguments. If you fail to do this, filtering by scheme doesn't work. For example, `AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)` makes cookies run automatically. +>When adding multiple authentication middlewares, ensure that no middleware is configured to run automatically. Invoking `AddAuthentication` with no arguments ensures that no middleware is configured to run automatically. If the app does **not** + invoke `AddAuthentication` with no arguments, filtering by scheme doesn't work. For example, calling + `AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)` makes cookies run automatically. # [ASP.NET Core 1.x](#tab/aspnetcore1x) @@ -70,13 +72,17 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerF In the preceding code, two authentication middlewares have been added: one for cookies and one for bearer. >[!NOTE] ->When adding multiple authentication middlewares, ensure that no middleware is configured to run automatically. You do this by setting the `AuthenticationOptions.AutomaticAuthenticate` property to false. If you fail to do this, filtering by scheme doesn't work. +>When adding multiple authentication middlewares, ensure that no middleware is configured to run automatically. An app ensures that no middleware is configured to run automatically by setting the `AuthenticationOptions.AutomaticAuthenticate` property to false. If the app fails to set`AuthenticationOptions.AutomaticAuthenticate` to false, filtering by scheme doesn't work. --- ## Selecting the scheme with the Authorize attribute -At the point of authorization, you indicate the middleware to be used. The simplest way to select the middleware with which you wish to authorize is to pass a comma-delimited list of authentication schemes to the `[Authorize]` attribute. The `[Authorize]` attribute specifies the authentication scheme or schemes to use regardless of whether a default is configured. For example: +At the point of authorization, the app indicates the middleware to be used. The simplest way to select the middleware with which the app will authorize: + +* Pass a comma-delimited list of authentication schemes to the `[Authorize]` attribute. + +The `[Authorize]` attribute specifies the authentication scheme or schemes to use regardless of whether a default is configured. For example: # [ASP.NET Core 2.x](#tab/aspnetcore2x) @@ -94,7 +100,7 @@ public class MixedController : Controller --- -In the example above, both the cookie and bearer middlewares run and have a chance to create and append an identity for the current user. By specifying a single scheme only, the specified middleware runs. +In the preceding example, both the cookie and bearer middlewares run and have a chance to create and append an identity for the current user. By specifying a single scheme only, the specified middleware runs. # [ASP.NET Core 2.x](#tab/aspnetcore2x) @@ -112,7 +118,8 @@ public class MixedController : Controller --- -In this case, only the middleware with the "Bearer" scheme runs. Any cookie-based identities are ignored. + +In the preceding code , only the middleware with the "Bearer" scheme runs. Any cookie-based identities are ignored. ## Selecting the scheme with policies @@ -130,4 +137,4 @@ services.AddAuthorization(options => }); ``` -In this example, the "Over18" policy only runs against the identity created by the "Bearer" middleware. +In the preceding example, the "Over18" policy only runs against the identity created by the "Bearer" middleware. From 9d6cafcdc85644bbcc3a217a8f7bfcdddcc5bad6 Mon Sep 17 00:00:00 2001 From: Scott Addie Date: Thu, 12 Oct 2017 09:27:46 -0500 Subject: [PATCH 11/15] Minor tweaks --- .../authorization/limitingidentitybyscheme.md | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/aspnetcore/security/authorization/limitingidentitybyscheme.md b/aspnetcore/security/authorization/limitingidentitybyscheme.md index a76e30712b..6271855789 100644 --- a/aspnetcore/security/authorization/limitingidentitybyscheme.md +++ b/aspnetcore/security/authorization/limitingidentitybyscheme.md @@ -39,9 +39,7 @@ public void ConfigureServices(IServiceCollection services) In the preceding code, two authentication services have been added: one for cookies and one for bearer. >[!NOTE] ->When adding multiple authentication middlewares, ensure that no middleware is configured to run automatically. Invoking `AddAuthentication` with no arguments ensures that no middleware is configured to run automatically. If the app does **not** - invoke `AddAuthentication` with no arguments, filtering by scheme doesn't work. For example, calling - `AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)` makes cookies run automatically. +>When adding multiple authentication middlewares, ensure that no middleware is configured to run automatically. Invoking `AddAuthentication` with no arguments ensures that no middleware is configured to run automatically. If the app invokes `AddAuthentication` with arguments, filtering by scheme doesn't work. For example, calling `AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)` makes cookies run automatically. # [ASP.NET Core 1.x](#tab/aspnetcore1x) @@ -72,17 +70,13 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerF In the preceding code, two authentication middlewares have been added: one for cookies and one for bearer. >[!NOTE] ->When adding multiple authentication middlewares, ensure that no middleware is configured to run automatically. An app ensures that no middleware is configured to run automatically by setting the `AuthenticationOptions.AutomaticAuthenticate` property to false. If the app fails to set`AuthenticationOptions.AutomaticAuthenticate` to false, filtering by scheme doesn't work. +>When adding multiple authentication middlewares, ensure that no middleware is configured to run automatically. An app ensures that no middleware is configured to run automatically by setting the `AuthenticationOptions.AutomaticAuthenticate` property to false. If the app fails to set `AuthenticationOptions.AutomaticAuthenticate` to false, filtering by scheme doesn't work. --- ## Selecting the scheme with the Authorize attribute -At the point of authorization, the app indicates the middleware to be used. The simplest way to select the middleware with which the app will authorize: - -* Pass a comma-delimited list of authentication schemes to the `[Authorize]` attribute. - -The `[Authorize]` attribute specifies the authentication scheme or schemes to use regardless of whether a default is configured. For example: +At the point of authorization, the app indicates the middleware to be used. Select the middleware with which the app will authorize by passing a comma-delimited list of authentication schemes to `[Authorize]`. The `[Authorize]` attribute specifies the authentication scheme or schemes to use regardless of whether a default is configured. For example: # [ASP.NET Core 2.x](#tab/aspnetcore2x) @@ -118,8 +112,7 @@ public class MixedController : Controller --- - -In the preceding code , only the middleware with the "Bearer" scheme runs. Any cookie-based identities are ignored. +In the preceding code, only the middleware with the "Bearer" scheme runs. Any cookie-based identities are ignored. ## Selecting the scheme with policies @@ -137,4 +130,4 @@ services.AddAuthorization(options => }); ``` -In the preceding example, the "Over18" policy only runs against the identity created by the "Bearer" middleware. +In the preceding example, the "Over18" policy only runs against the identity created by the "Bearer" middleware. From c857c8f187187dcf2abfe88dfd67859bd92a5f8f Mon Sep 17 00:00:00 2001 From: Scott Addie Date: Thu, 12 Oct 2017 09:35:20 -0500 Subject: [PATCH 12/15] application --> app --- aspnetcore/security/authorization/limitingidentitybyscheme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aspnetcore/security/authorization/limitingidentitybyscheme.md b/aspnetcore/security/authorization/limitingidentitybyscheme.md index 6271855789..087fe51c68 100644 --- a/aspnetcore/security/authorization/limitingidentitybyscheme.md +++ b/aspnetcore/security/authorization/limitingidentitybyscheme.md @@ -14,7 +14,7 @@ uid: security/authorization/limitingidentitybyscheme --- # Limiting identity by scheme -In some scenarios, such as Single Page Applications (SPAs), it's common to use multiple authentication methods. For example, the application may use cookie-based authentication to log in and JWT bearer authentication for JavaScript requests. In some cases, the app may have multiple instances of an authentication middleware. For example, two cookie middlewares where one contains a basic identity and one is created when a multi-factor authentication (MFA) has been triggered. MFA may be triggered because the user requested an operation that requires extra security. +In some scenarios, such as Single Page Applications (SPAs), it's common to use multiple authentication methods. For example, the app may use cookie-based authentication to log in and JWT bearer authentication for JavaScript requests. In some cases, the app may have multiple instances of an authentication middleware. For example, two cookie middlewares where one contains a basic identity and one is created when a multi-factor authentication (MFA) has been triggered. MFA may be triggered because the user requested an operation that requires extra security. # [ASP.NET Core 2.x](#tab/aspnetcore2x) From fb8d79c28ef6529999f404e7d867fa31372391e6 Mon Sep 17 00:00:00 2001 From: Scott Addie Date: Thu, 12 Oct 2017 12:20:58 -0500 Subject: [PATCH 13/15] Implement Rick's suggestion in cookie doc --- aspnetcore/security/authentication/cookie.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aspnetcore/security/authentication/cookie.md b/aspnetcore/security/authentication/cookie.md index eaa25b6080..4c0ff2e2a6 100644 --- a/aspnetcore/security/authentication/cookie.md +++ b/aspnetcore/security/authentication/cookie.md @@ -71,7 +71,7 @@ The code snippets above configure some or all of the following options: * `AccessDeniedPath` - This is the relative path to which requests redirect when a user attempts to access a resource but does not pass any [authorization policies](xref:security/authorization/policies#security-authorization-policies-based) for that resource. -* `AuthenticationScheme` - This is a value by which a particular cookie authentication scheme is known. This is useful when there are multiple instances of cookie authentication and you want to [limit authorization to one instance](xref:security/authorization/limitingidentitybyscheme). +* `AuthenticationScheme` - This is a value by which a particular cookie authentication scheme is known. This is useful when there are multiple instances of cookie authentication and the app needs to [limit authorization to one instance](xref:security/authorization/limitingidentitybyscheme). * `AutomaticAuthenticate` - This flag is relevant only for ASP.NET Core 1.x. It indicates that the cookie authentication should run on every request and attempt to validate and reconstruct any serialized principal it created. From 9acd1a1db1c48765ef1d34ea3b85270a6488f4bc Mon Sep 17 00:00:00 2001 From: Scott Addie Date: Thu, 12 Oct 2017 12:22:13 -0500 Subject: [PATCH 14/15] Implement Rick's suggestion in cookie doc --- aspnetcore/security/authentication/cookie.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aspnetcore/security/authentication/cookie.md b/aspnetcore/security/authentication/cookie.md index eaa25b6080..4c0ff2e2a6 100644 --- a/aspnetcore/security/authentication/cookie.md +++ b/aspnetcore/security/authentication/cookie.md @@ -71,7 +71,7 @@ The code snippets above configure some or all of the following options: * `AccessDeniedPath` - This is the relative path to which requests redirect when a user attempts to access a resource but does not pass any [authorization policies](xref:security/authorization/policies#security-authorization-policies-based) for that resource. -* `AuthenticationScheme` - This is a value by which a particular cookie authentication scheme is known. This is useful when there are multiple instances of cookie authentication and you want to [limit authorization to one instance](xref:security/authorization/limitingidentitybyscheme). +* `AuthenticationScheme` - This is a value by which a particular cookie authentication scheme is known. This is useful when there are multiple instances of cookie authentication and the app needs to [limit authorization to one instance](xref:security/authorization/limitingidentitybyscheme). * `AutomaticAuthenticate` - This flag is relevant only for ASP.NET Core 1.x. It indicates that the cookie authentication should run on every request and attempt to validate and reconstruct any serialized principal it created. From 9332fc59406e4d855853e8e78d11f8bbdda1f174 Mon Sep 17 00:00:00 2001 From: Scott Addie Date: Thu, 12 Oct 2017 15:14:00 -0500 Subject: [PATCH 15/15] React to feedback --- .../authorization/limitingidentitybyscheme.md | 34 +++++++++++-------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/aspnetcore/security/authorization/limitingidentitybyscheme.md b/aspnetcore/security/authorization/limitingidentitybyscheme.md index 087fe51c68..598f323c75 100644 --- a/aspnetcore/security/authorization/limitingidentitybyscheme.md +++ b/aspnetcore/security/authorization/limitingidentitybyscheme.md @@ -1,20 +1,20 @@ --- -title: Limiting identity by scheme - ASP.NET Core +title: Authorize with a specific scheme - ASP.NET Core author: rick-anderson -description: This article explains how to limit identity to a specific schema when working with multiple authentication methods. +description: This article explains how to limit identity to a specific scheme when working with multiple authentication methods. keywords: ASP.NET Core,identity,authentication scheme ms.author: riande manager: wpickett -ms.date: 10/10/2017 +ms.date: 10/12/2017 ms.topic: article ms.assetid: d3d6ca1b-b4b5-4bf7-898e-dcd90ec1bf8c ms.technology: aspnet ms.prod: asp.net-core uid: security/authorization/limitingidentitybyscheme --- -# Limiting identity by scheme +# Authorize with a specific scheme -In some scenarios, such as Single Page Applications (SPAs), it's common to use multiple authentication methods. For example, the app may use cookie-based authentication to log in and JWT bearer authentication for JavaScript requests. In some cases, the app may have multiple instances of an authentication middleware. For example, two cookie middlewares where one contains a basic identity and one is created when a multi-factor authentication (MFA) has been triggered. MFA may be triggered because the user requested an operation that requires extra security. +In some scenarios, such as Single Page Applications (SPAs), it's common to use multiple authentication methods. For example, the app may use cookie-based authentication to log in and JWT bearer authentication for JavaScript requests. In some cases, the app may have multiple instances of an authentication handler. For example, two cookie handlers where one contains a basic identity and one is created when a multi-factor authentication (MFA) has been triggered. MFA may be triggered because the user requested an operation that requires extra security. # [ASP.NET Core 2.x](#tab/aspnetcore2x) @@ -36,10 +36,10 @@ public void ConfigureServices(IServiceCollection services) }); ``` -In the preceding code, two authentication services have been added: one for cookies and one for bearer. +In the preceding code, two authentication handlers have been added: one for cookies and one for bearer. >[!NOTE] ->When adding multiple authentication middlewares, ensure that no middleware is configured to run automatically. Invoking `AddAuthentication` with no arguments ensures that no middleware is configured to run automatically. If the app invokes `AddAuthentication` with arguments, filtering by scheme doesn't work. For example, calling `AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)` makes cookies run automatically. +>Specifying the default scheme results in the `HttpContext.User` property being set to that identity. If that behavior isn't desired, disable it by invoking the parameterless form of `AddAuthentication`. # [ASP.NET Core 1.x](#tab/aspnetcore1x) @@ -63,20 +63,21 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerF AuthenticationScheme = "Bearer", AutomaticAuthenticate = false, Audience = "http://localhost:5001/", - Authority = "http://localhost:5000/" + Authority = "http://localhost:5000/", + RequireHttpsMetadata = false }); ``` In the preceding code, two authentication middlewares have been added: one for cookies and one for bearer. >[!NOTE] ->When adding multiple authentication middlewares, ensure that no middleware is configured to run automatically. An app ensures that no middleware is configured to run automatically by setting the `AuthenticationOptions.AutomaticAuthenticate` property to false. If the app fails to set `AuthenticationOptions.AutomaticAuthenticate` to false, filtering by scheme doesn't work. +>Specifying the default scheme results in the `HttpContext.User` property being set to that identity. If that behavior isn't desired, disable it by setting the `AuthenticationOptions.AutomaticAuthenticate` property to `false`. --- ## Selecting the scheme with the Authorize attribute -At the point of authorization, the app indicates the middleware to be used. Select the middleware with which the app will authorize by passing a comma-delimited list of authentication schemes to `[Authorize]`. The `[Authorize]` attribute specifies the authentication scheme or schemes to use regardless of whether a default is configured. For example: +At the point of authorization, the app indicates the handler to be used. Select the handler with which the app will authorize by passing a comma-delimited list of authentication schemes to `[Authorize]`. The `[Authorize]` attribute specifies the authentication scheme or schemes to use regardless of whether a default is configured. For example: # [ASP.NET Core 2.x](#tab/aspnetcore2x) @@ -94,7 +95,7 @@ public class MixedController : Controller --- -In the preceding example, both the cookie and bearer middlewares run and have a chance to create and append an identity for the current user. By specifying a single scheme only, the specified middleware runs. +In the preceding example, both the cookie and bearer handlers run and have a chance to create and append an identity for the current user. By specifying a single scheme only, the corresponding handler runs. # [ASP.NET Core 2.x](#tab/aspnetcore2x) @@ -112,7 +113,7 @@ public class MixedController : Controller --- -In the preceding code, only the middleware with the "Bearer" scheme runs. Any cookie-based identities are ignored. +In the preceding code, only the handler with the "Bearer" scheme runs. Any cookie-based identities are ignored. ## Selecting the scheme with policies @@ -125,9 +126,14 @@ services.AddAuthorization(options => { policy.AuthenticationSchemes.Add("Bearer"); policy.RequireAuthenticatedUser(); - policy.Requirements.Add(new Over18Requirement()); + policy.Requirements.Add(new MinimumAgeRequirement()); }); }); ``` -In the preceding example, the "Over18" policy only runs against the identity created by the "Bearer" middleware. +In the preceding example, the "Over18" policy only runs against the identity created by the "Bearer" handler. Use the policy by setting the `[Authorize]` attribute's `Policy` property: + +```csharp +[Authorize(Policy = "Over18")] +public class RegistrationController : Controller +```