Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions aspnetcore/migration/22-to-30.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ author: wadepickett
description: Learn how to migrate an ASP.NET Core 2.2 project to ASP.NET Core 3.0.
ms.author: wpickett
ms.custom: mvc
ms.date: 06/02/2023
ms.date: 07/10/2026
uid: migration/22-to-30
---
# Migrate from ASP.NET Core 2.2 to 3.0
Expand Down Expand Up @@ -841,7 +841,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#security-authorization-policies-based-authorization-handler), endpoint routing passes a different resource type to handlers than MVC. Handlers that expect the authorization handler context resource to be of type <xref:Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext> (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 <xref:Microsoft.AspNetCore.Routing.RouteEndpoint> (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 <xref:Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext> (the resource type [provided by MVC filters](xref:mvc/security/authorization/policies#access-mvc-request-context-in-handlers)) will need to be updated to handle resources of type <xref:Microsoft.AspNetCore.Routing.RouteEndpoint> (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.

Expand Down
2 changes: 1 addition & 1 deletion aspnetcore/migration/70-to-80.md
Original file line number Diff line number Diff line change
Expand Up @@ -614,7 +614,7 @@ This problem is under evaluation for a new framework feature in [MapRazorCompone
});
```

* Register a custom `AuthorizationHandler` that [checks the `HttpContext`](xref:security/authorization/policies#access-mvc-request-context-in-handlers) to allow the `/_framework/blazor.server.js` file through.
* Register a custom `AuthorizationHandler` that [checks the `HttpContext`](xref:mvc/security/authorization/policies#access-mvc-request-context-in-handlers) to allow the `/_framework/blazor.server.js` file through.

## Docker

Expand Down
69 changes: 69 additions & 0 deletions aspnetcore/mvc/security/authorization/policies.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
---
title: Policy-based authorization in ASP.NET Core MVC
ai-usage: ai-assisted
author: wadepickett
description: Learn how to create and use authorization policy handlers for enforcing authorization requirements in an ASP.NET Core MVC app.
monikerRange: '>= aspnetcore-3.1'
ms.author: wpickett
ms.custom: mvc
ms.date: 07/10/2026
uid: mvc/security/authorization/policies
---
# Policy-based authorization in ASP.NET Core MVC

This article provides additional MVC policy-based authorization scenarios following <xref:security/authorization/policies>, which should be read before this article when learning about policy-based authorization.

## Apply policies to MVC controllers

Apply policies to controllers using the `[Authorize]` attribute with the policy name:

:::moniker range=">= aspnetcore-6.0"

:::code language="csharp" source="~/../AspNetCore.Docs.Samples/security/authorization/policies/6.0/AuthorizationPoliciesSample/Controllers/AtLeast21Controller.cs" id="snippet" highlight="1":::

If multiple policies are applied at the controller and action levels, ***all*** policies must pass before access is granted:

:::code language="csharp" source="~/../AspNetCore.Docs.Samples/security/authorization/policies/6.0/AuthorizationPoliciesSample/Controllers/AtLeast21Controller2.cs" id="snippet" highlight="1,4":::

:::moniker-end

:::moniker range="< aspnetcore-6.0"

:::code language="csharp" source="~/../AspNetCore.Docs.Samples/security/authorization/policies/PoliciesAuthApp1/Controllers/AlcoholPurchaseController.cs" id="snippet_AlcoholPurchaseControllerClass" highlight="4":::

:::moniker-end

## Access MVC request context in handlers

The <xref:Microsoft.AspNetCore.Authorization.AuthorizationHandler%601.HandleRequirementAsync%2A?displayProperty=nameWithType> method has two parameters: an <xref:Microsoft.AspNetCore.Authorization.AuthorizationHandlerContext> and the `TRequirement` being handled. Frameworks such as MVC or SignalR are free to add any object to the <xref:Microsoft.AspNetCore.Authorization.AuthorizationHandlerContext.Resource%2A?displayProperty=nameWithType> property to pass extra information.

When using endpoint routing, authorization is typically handled by the Authorization Middleware, and the <xref:Microsoft.AspNetCore.Authorization.AuthorizationHandlerContext.Resource%2A> property is an instance of <xref:Microsoft.AspNetCore.Http.HttpContext>. The context is used to access the current endpoint, which can be used to probe the underlying resource to which you're routing:

```csharp
if (context.Resource is HttpContext httpContext)
{
var endpoint = httpContext.GetEndpoint();
var actionDescriptor =
endpoint?.Metadata.GetMetadata<ControllerActionDescriptor>();
...
}
```

With traditional routing, or when authorization happens as part of MVC's authorization filter, the value of <xref:Microsoft.AspNetCore.Authorization.AuthorizationHandlerContext.Resource%2A> is an <xref:Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext> instance. This property provides access to <xref:Microsoft.AspNetCore.Http.HttpContext>, <xref:Microsoft.AspNetCore.Routing.RouteData>, and everything else provided by MVC and Razor Pages.

The use of the <xref:Microsoft.AspNetCore.Authorization.AuthorizationHandlerContext.Resource%2A> property is framework-specific. Using information in the property limits your authorization policies to particular frameworks. Cast the property using the `is` keyword, and then confirm the cast has succeeded to ensure your code doesn't crash with an <xref:System.InvalidCastException> when run on other frameworks. When the cast succeeds, examine MVC-specific data, such as routing data:

```csharp
using Microsoft.AspNetCore.Mvc.Filters;

...

if (context.Resource is AuthorizationFilterContext mvcContext)
{
var routeValues = mvcContext.RouteData.Values;
...
}
```

> [!NOTE]
> Endpoint routing passes <xref:Microsoft.AspNetCore.Routing.RouteEndpoint> to authorization handlers, unlike traditional routing in MVC apps, which use an authorization handler context resource of type <xref:Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext>. If the app uses MVC authorization filters along with endpoint routing authorization, it may be necessary to handle both types of resources.
4 changes: 2 additions & 2 deletions aspnetcore/mvc/security/authorization/resource-based.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ author: wadepickett
description: Learn how to implement resource-based authorization in an ASP.NET Core MVC app when an [Authorize] attribute doesn't suffice.
ms.author: wpickett
ms.custom: mvc
ms.date: 05/20/2026
ms.date: 07/10/2026
uid: mvc/security/authorization/resource-based
---
# Resource-based authorization in ASP.NET Core MVC
Expand Down Expand Up @@ -84,7 +84,7 @@ public async Task<IActionResult> Edit(Guid documentId)

## Create a resource-based handler

Creating a resource-based authorization handler is similar to [creating a plain requirements handler](xref:security/authorization/policies#security-authorization-policies-based-authorization-handler). Create a custom requirement class and implement a requirement handler class. For more information on creating a requirement class, see the [Policy-based authorization: Requirements](xref:security/authorization/policies#requirements).
Creating a resource-based authorization handler is similar to [creating a plain requirements handler](xref:security/authorization/policies#authorization-handlers). Create a custom requirement class and implement a requirement handler class. For more information on creating a requirement class, see <xref:security/authorization/policies#requirements-and-policy-registration>.

The handler class specifies the requirement and resource type. The following example demonstrates a handler utilizing a `SameAuthorRequirement` requirement and a `Document` resource:

Expand Down
34 changes: 34 additions & 0 deletions aspnetcore/razor-pages/security/authorization/policies.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
title: Policy-based authorization in ASP.NET Core Razor Pages
ai-usage: ai-assisted
author: wadepickett
description: Learn how to create and use authorization policy handlers for enforcing authorization requirements in an ASP.NET Core Razor Pages app.
monikerRange: '>= aspnetcore-3.1'
ms.author: wpickett
ms.custom: mvc
ms.date: 07/10/2026
uid: razor-pages/security/authorization/policies
---
# Policy-based authorization in ASP.NET Core Razor Pages

This article provides additional Razor Pages policy-based authorization scenarios following <xref:security/authorization/policies>, which should be read before this article when learning about policy-based authorization.

## Apply policies to Razor Pages

Apply policies to Razor Pages using the `[Authorize]` attribute with the policy name:

:::moniker range=">= aspnetcore-6.0"

:::code language="csharp" source="~/../AspNetCore.Docs.Samples/security/authorization/policies/6.0/AuthorizationPoliciesSample/Pages/AtLeast21.cshtml.cs" highlight="6":::

:::moniker-end

:::moniker range="< aspnetcore-6.0"

:::code language="csharp" source="~/../AspNetCore.Docs.Samples/security/authorization/policies/PoliciesAuthApp2/Pages/AlcoholPurchase.cshtml.cs" id="snippet_AlcoholPurchaseModelClass" highlight="4":::

:::moniker-end

Policies can't be applied at the page handler level, they must be applied to the <xref:Microsoft.AspNetCore.Mvc.RazorPages.PageModel> class.

Policies can also be applied to pages using an [authorization convention](xref:razor-pages/security/authorization/conventions).
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ author: wadepickett
description: Learn how to implement resource-based authorization in an ASP.NET Core Razor Pages app when an [Authorize] attribute doesn't suffice.
ms.author: wpickett
ms.custom: mvc
ms.date: 05/20/2026
ms.date: 07/10/2026
uid: razor-pages/security/authorization/resource-based
---
# Resource-based authorization in ASP.NET Core Razor Pages
Expand Down Expand Up @@ -83,7 +83,7 @@ public async Task<IActionResult> OnGetAsync(Guid documentId)

## Create a resource-based handler

Creating a resource-based authorization handler is similar to [creating a plain requirements handler](xref:security/authorization/policies#security-authorization-policies-based-authorization-handler). Create a custom requirement class and implement a requirement handler class. For more information on creating a requirement class, see the [Policy-based authorization: Requirements](xref:security/authorization/policies#requirements).
Creating a resource-based authorization handler is similar to [creating a plain requirements handler](xref:security/authorization/policies#authorization-handlers). Create a custom requirement class and implement a requirement handler class. For more information on creating a requirement class, see <xref:security/authorization/policies#requirements-and-policy-registration>.

The handler class specifies the requirement and resource type. The following example demonstrates a handler utilizing a `SameAuthorRequirement` requirement and a `Document` resource:

Expand Down
4 changes: 2 additions & 2 deletions aspnetcore/release-notes/aspnetcore-5.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ author: wadepickett
description: Learn about the new features in ASP.NET Core in .NET 5.
ms.author: wpickett
ms.custom: mvc
ms.date: 07/29/2025
ms.date: 07/10/2026
uid: aspnetcore-5.0
---
# What's new in ASP.NET Core in .NET 5
Expand Down Expand Up @@ -344,7 +344,7 @@ Prior to .NET 5, building and publishing a *Dockerfile* for an ASP.NET Core app

### Microsoft Entra ID authentication with Microsoft.Identity.Web

The ASP.NET Core project templates now integrate with <xref:Microsoft.Identity.Web?displayProperty=fullName> to handle authentication with [Microsoft Entra ID](/azure/active-directory/fundamentals/active-directory-whatis). The [Microsoft.Identity.Web package](https://www.nuget.org/packages/Microsoft.Identity.Web/) provides:
The ASP.NET Core project templates now integrate with <xref:Microsoft.Identity.Web?displayProperty=fullName> to handle authentication with [Microsoft Entra ID](/entra/fundamentals/what-is-entra). The [Microsoft.Identity.Web package](https://www.nuget.org/packages/Microsoft.Identity.Web/) provides:

* A better experience for authentication through Microsoft Entra ID.
* An easier way to access Azure resources on behalf of your users, including [Microsoft Graph](/graph/overview). See the [Microsoft.Identity.Web sample](https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2), which starts with a basic login and advances through multi-tenancy, using Azure APIs, using Microsoft Graph, and protecting your own APIs. `Microsoft.Identity.Web` is available alongside .NET 5.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ You can decode the token in an online JWT decoder, such as [`jwt.ms`](https://jw
"alg": "HS256",
"typ": "JWT"
}.{
"unique_name": "guard",
"sub": "guard",
"unique_name": "{USER}",
"sub": "{USER}",
"jti": "6cd613ed",
"birthdate": "1989-01-01",
"aud": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ author: tdykstra
description: This article explains how to customize the result handling of AuthorizationMiddleware.
ms.author: tdykstra
monikerRange: '>= aspnetcore-5.0'
ms.date: 03/24/2022
ms.date: 07/10/2026
uid: security/authorization/authorizationmiddlewareresulthandler
---
# Customize the behavior of `AuthorizationMiddleware`
Expand Down
6 changes: 3 additions & 3 deletions aspnetcore/security/authorization/dependencyinjection.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ author: tdykstra
description: Learn how to inject authorization requirement handlers into an ASP.NET Core app using dependency injection.
monikerRange: ">= aspnetcore-2.1"
ms.author: tdykstra
ms.date: 03/25/2022
ms.date: 07/10/2026
uid: security/authorization/dependencyinjection
---
# Dependency injection in requirement handlers in ASP.NET Core

:::moniker range=">= aspnetcore-6.0"

[Authorization handlers must be registered](xref:security/authorization/policies#security-authorization-policies-based-handler-registration) in the service collection during configuration using [dependency injection](xref:fundamentals/dependency-injection).
[Authorization handlers must be registered](xref:security/authorization/policies#handler-registration) in the service collection during configuration using [dependency injection](xref:fundamentals/dependency-injection).

Suppose you had a repository of rules you wanted to evaluate inside an authorization handler and that repository was registered in the service collection. Authorization resolves and injects that into the constructor.

Expand Down Expand Up @@ -52,7 +52,7 @@ An instance of the handler is created when the app starts, and DI injects the re

:::moniker range="< aspnetcore-6.0"

[Authorization handlers must be registered](xref:security/authorization/policies#security-authorization-policies-based-handler-registration) in the service collection during configuration using [dependency injection](xref:fundamentals/dependency-injection).
[Authorization handlers must be registered](xref:security/authorization/policies#handler-registration) in the service collection during configuration using [dependency injection](xref:fundamentals/dependency-injection).

Suppose you had a repository of rules you wanted to evaluate inside an authorization handler and that repository was registered in the service collection. Authorization resolves and injects that into the constructor.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ author: mjrousos
description: Learn how to use a custom IAuthorizationPolicyProvider in an ASP.NET Core app to dynamically generate authorization policies.
ms.author: wpickett
ms.custom: mvc
ms.date: 05/15/2026
ms.date: 07/10/2026
uid: security/authorization/iauthorizationpolicyprovider

# customer intent: As an ASP.NET developer, I want to use a custom IAuthorizationPolicyProvider in my ASP.NET Core app, so I can dynamically generate authorization policies.
Expand Down Expand Up @@ -180,7 +180,7 @@ public Task<AuthorizationPolicy> GetFallbackPolicyAsync() =>

To use custom policies from an `IAuthorizationPolicyProvider`, you ***must***:

* Register the appropriate `AuthorizationHandler` types with dependency injection (described in [policy-based authorization](xref:security/authorization/policies#security-authorization-policies-based-authorization-handler)), as with all policy-based authorization scenarios.
* Register the appropriate `AuthorizationHandler` types with dependency injection (described in [policy-based authorization](xref:security/authorization/policies#authorization-handlers)), as with all policy-based authorization scenarios.

* Register the custom `IAuthorizationPolicyProvider` type in the application dependency injection service collection in `Startup.ConfigureServices` and replace the default policy provider.

Expand Down
Loading
Loading