From f321c59eba73b3cbca9e4975e276c84426926703 Mon Sep 17 00:00:00 2001 From: Kirk Larkin <6025110+serpent5@users.noreply.github.com> Date: Wed, 17 Jun 2020 22:53:29 +0100 Subject: [PATCH] Cover how to access HttpContext in an authz handler (#18837) * Swap content between monikers * Add note re HttpContext * Remove "ing"s --- aspnetcore/fundamentals/routing.md | 2 +- aspnetcore/migration/22-to-30.md | 2 +- aspnetcore/security/authorization/claims.md | 2 +- aspnetcore/security/authorization/policies.md | 48 ++++++++++--------- 4 files changed, 28 insertions(+), 26 deletions(-) diff --git a/aspnetcore/fundamentals/routing.md b/aspnetcore/fundamentals/routing.md index 55c53c0c59..395b6e49fa 100644 --- a/aspnetcore/fundamentals/routing.md +++ b/aspnetcore/fundamentals/routing.md @@ -822,7 +822,7 @@ The following links provide information on configuring endpoint metadata: * [Test authentication with the [Authorize] attribute](xref:security/authentication/identity#test-identity) * * [Selecting the scheme with the [Authorize] attribute](xref:security/authorization/limitingidentitybyscheme#selecting-the-scheme-with-the-authorize-attribute) -* [Applying policies using the [Authorize] attribute](xref:security/authorization/policies#applying-policies-to-mvc-controllers) +* [Apply policies using the [Authorize] attribute](xref:security/authorization/policies#apply-policies-to-mvc-controllers) * diff --git a/aspnetcore/migration/22-to-30.md b/aspnetcore/migration/22-to-30.md index 006bb9a3d6..9abb2dcf92 100644 --- a/aspnetcore/migration/22-to-30.md +++ b/aspnetcore/migration/22-to-30.md @@ -826,7 +826,7 @@ Protection is implemented for some scenarios. Endpoints Middleware throws an exc #### Custom authorization handlers -If the app uses custom [authorization handlers](xref:security/authorization/policies#authorization-handlers), endpoint routing passes a different resource type to handlers than MVC. Handlers that expect the authorization handler context resource to be of type (the resource type [provided by MVC filters](xref:security/authorization/policies#accessing-mvc-request-context-in-handlers)) will need to be updated to handle resources of type (the resource type given to authorization handlers by endpoint routing). +If the app uses custom [authorization handlers](xref:security/authorization/policies#authorization-handlers), endpoint routing passes a different resource type to handlers than MVC. Handlers that expect the authorization handler context resource to be of type (the resource type [provided by MVC filters](xref:security/authorization/policies#access-mvc-request-context-in-handlers)) will need to be updated to handle resources of type (the resource type given to authorization handlers by endpoint routing). MVC still uses `AuthorizationFilterContext` resources, so if the app uses MVC authorization filters along with endpoint routing authorization, it may be necessary to handle both types of resources. diff --git a/aspnetcore/security/authorization/claims.md b/aspnetcore/security/authorization/claims.md index 959435b4bc..5c6951926b 100644 --- a/aspnetcore/security/authorization/claims.md +++ b/aspnetcore/security/authorization/claims.md @@ -137,7 +137,7 @@ public void ConfigureServices(IServiceCollection services) ::: moniker-end ### Add a generic claim check -If the claim value isn't a single value or a transformation is required, use [RequireAssertion](/dotnet/api/microsoft.aspnetcore.authorization.authorizationpolicybuilder.requireassertion). For more information, see [Using a func to fulfill a policy](xref:security/authorization/policies#using-a-func-to-fulfill-a-policy). +If the claim value isn't a single value or a transformation is required, use [RequireAssertion](/dotnet/api/microsoft.aspnetcore.authorization.authorizationpolicybuilder.requireassertion). For more information, see [Use a func to fulfill a policy](xref:security/authorization/policies#use-a-func-to-fulfill-a-policy). ## Multiple Policy Evaluation diff --git a/aspnetcore/security/authorization/policies.md b/aspnetcore/security/authorization/policies.md index a2e1af0832..0de4bf5999 100644 --- a/aspnetcore/security/authorization/policies.md +++ b/aspnetcore/security/authorization/policies.md @@ -102,15 +102,15 @@ public void ConfigureServices(IServiceCollection services) Use or `[Authorize(Policy = "Something")]` for authorization. -## Applying policies to MVC controllers +## Apply policies to MVC controllers -If you're using Razor Pages, see [Applying policies to Razor Pages](#applying-policies-to-razor-pages) in this document. +If you're using Razor Pages, see [Apply policies to Razor Pages](#apply-policies-to-razor-pages) in this document. Policies are applied to controllers by using the `[Authorize]` attribute with the policy name. For example: [!code-csharp[](policies/samples/PoliciesAuthApp1/Controllers/AlcoholPurchaseController.cs?name=snippet_AlcoholPurchaseControllerClass&highlight=4)] -## Applying policies to Razor Pages +## Apply policies to Razor Pages Policies are applied to Razor Pages by using the `[Authorize]` attribute with the policy name. For example: @@ -200,7 +200,7 @@ In cases where you want evaluation to be on an **OR** basis, implement multiple Ensure that both handlers are [registered](xref:security/authorization/policies#security-authorization-policies-based-handler-registration). If either handler succeeds when a policy evaluates the `BuildingEntryRequirement`, the policy evaluation succeeds. -## Using a func to fulfill a policy +## Use a func to fulfill a policy There may be situations in which fulfilling a policy is simple to express in code. It's possible to supply a `Func` when configuring your policy with the `RequireAssertion` policy builder. @@ -208,11 +208,23 @@ For example, the previous `BadgeEntryHandler` could be rewritten as follows: [!code-csharp[](policies/samples/3.0PoliciesAuthApp1/Startup.cs?range=42-43,47-53)] -## Accessing MVC request context in handlers +## Access MVC request context in handlers -The `HandleRequirementAsync` method you implement in an authorization handler has two parameters: an `AuthorizationHandlerContext` and the `TRequirement` you are handling. Frameworks such as MVC or Jabbr are free to add any object to the `Resource` property on the `AuthorizationHandlerContext` to pass extra information. +The `HandleRequirementAsync` method you implement in an authorization handler has two parameters: an `AuthorizationHandlerContext` and the `TRequirement` you are handling. Frameworks such as MVC or SignalR are free to add any object to the `Resource` property on the `AuthorizationHandlerContext` to pass extra information. -For example, MVC passes an instance of [AuthorizationFilterContext](/dotnet/api/?term=AuthorizationFilterContext) in the `Resource` property. This property provides access to `HttpContext`, `RouteData`, and everything else provided by MVC and Razor Pages. +When using endpoint routing, authorization is typically handled by the Authorization Middleware. In this case, the `Resource` property is an instance of . The endpoint can be used to probe the underlying resource to which you're routing. For example: + +```csharp +if (context.Resource is Endpoint endpoint) +{ + var actionDescriptor = endpoint.Metadata.GetMetadata(); + ... +} +``` + +The endpoint doesn't provide access to the current `HttpContext`. When using endpoint routing, use `IHttpContextAcessor` to access `HttpContext` inside of an authorization handler. For more information, see [Use HttpContext from custom components](xref:fundamentals/httpcontext#use-httpcontext-from-custom-components). + +With traditional routing, or when authorization happens as part of MVC's authorization filter, the value of `Resource` is an instance. This property provides access to `HttpContext`, `RouteData`, and everything else provided by MVC and Razor Pages. The use of the `Resource` property is framework specific. Using information in the `Resource` property limits your authorization policies to particular frameworks. You should cast the `Resource` property using the `is` keyword, and then confirm the cast has succeeded to ensure your code doesn't crash with an `InvalidCastException` when run on other frameworks: @@ -319,15 +331,15 @@ public void ConfigureServices(IServiceCollection services) Use or `[Authorize(Policy = "Something")]` for authorization. -## Applying policies to MVC controllers +## Apply policies to MVC controllers -If you're using Razor Pages, see [Applying policies to Razor Pages](#applying-policies-to-razor-pages) in this document. +If you're using Razor Pages, see [Apply policies to Razor Pages](#apply-policies-to-razor-pages) in this document. Policies are applied to controllers by using the `[Authorize]` attribute with the policy name. For example: [!code-csharp[](policies/samples/PoliciesAuthApp1/Controllers/AlcoholPurchaseController.cs?name=snippet_AlcoholPurchaseControllerClass&highlight=4)] -## Applying policies to Razor Pages +## Apply policies to Razor Pages Policies are applied to Razor Pages by using the `[Authorize]` attribute with the policy name. For example: @@ -417,7 +429,7 @@ In cases where you want evaluation to be on an **OR** basis, implement multiple Ensure that both handlers are [registered](xref:security/authorization/policies#security-authorization-policies-based-handler-registration). If either handler succeeds when a policy evaluates the `BuildingEntryRequirement`, the policy evaluation succeeds. -## Using a func to fulfill a policy +## Use a func to fulfill a policy There may be situations in which fulfilling a policy is simple to express in code. It's possible to supply a `Func` when configuring your policy with the `RequireAssertion` policy builder. @@ -425,21 +437,11 @@ For example, the previous `BadgeEntryHandler` could be rewritten as follows: [!code-csharp[](policies/samples/PoliciesAuthApp1/Startup.cs?range=50-51,55-61)] -## Accessing MVC request context in handlers +## Access MVC request context in handlers The `HandleRequirementAsync` method you implement in an authorization handler has two parameters: an `AuthorizationHandlerContext` and the `TRequirement` you are handling. Frameworks such as MVC or SignalR are free to add any object to the `Resource` property on the `AuthorizationHandlerContext` to pass extra information. -When using endpoint routing, authorization is typically handled by the Authorization Middleware. In this case, the `Resource` property is an instance of . The endpoint can be used to probe the underlying the resource to which you're routing. For example: - -```csharp -if (context.Resource is Endpoint endpoint) -{ - var actionDescriptor = endpoint.Metadata.GetMetadata(); - ... -} -``` - -With traditional routing, or when authorization happens as part of MVC's authorization filter, the value of `Resource` is an instance. This property provides access to `HttpContext`, `RouteData`, and everything else provided by MVC and Razor Pages. +For example, MVC passes an instance of [AuthorizationFilterContext](/dotnet/api/?term=AuthorizationFilterContext) in the `Resource` property. This property provides access to `HttpContext`, `RouteData`, and everything else provided by MVC and Razor Pages. The use of the `Resource` property is framework specific. Using information in the `Resource` property limits your authorization policies to particular frameworks. You should cast the `Resource` property using the `is` keyword, and then confirm the cast has succeeded to ensure your code doesn't crash with an `InvalidCastException` when run on other frameworks: