Skip to content

Policy-based authorization article overhaul#37231

Open
guardrex wants to merge 12 commits into
mainfrom
guardrex/policy-based-authz
Open

Policy-based authorization article overhaul#37231
guardrex wants to merge 12 commits into
mainfrom
guardrex/policy-based-authz

Conversation

@guardrex

@guardrex guardrex commented Jun 5, 2026

Copy link
Copy Markdown
Collaborator

Fixes #35817

Tom ... I worked quite long time on this one, longer than usual. The current article (live link) seems like it has a lot of problems to address.

Notes

  • I'll ping Wade when he gets back to look everything over for a possible patch PR later. Unless you think we need it, I don't plan on requesting an engineering review.
  • Per Dan's request, I'm moving the RP and MVC content to their own articles under their nodes. The main doc set article uses Blazor examples.
  • The Blazor code cross-links pull from the new Blazor authz sample app in the main samples repo, which I'm using to cover all of the scenarios in the security > authorization node (Dan's original master issue). I didn't do much with the old samples. I stripped namespaces in some of the code. Those old samples still provide sample code in the main doc set article, which is focused on Blazor, and the non-Blazor namespaces in those old samples confuse the presentation.
  • I took a heavy hand with section ordering, section naming, and content phrasing throughout the article. I'm 👂 for your bug fixes and suggestions.
  • I 💀 the INCLUDES content approach. No broken links in prior version content now. 🎉

Internal previews

Toggle expand/collapse
📄 File 🔗 Preview link
aspnetcore/migration/22-to-30.md aspnetcore/migration/22-to-30
aspnetcore/migration/70-to-80.md aspnetcore/migration/70-to-80
aspnetcore/mvc/security/authorization/policies.md aspnetcore/mvc/security/authorization/policies
aspnetcore/mvc/security/authorization/resource-based.md aspnetcore/mvc/security/authorization/resource-based
aspnetcore/razor-pages/security/authorization/policies.md aspnetcore/razor-pages/security/authorization/policies
aspnetcore/razor-pages/security/authorization/resource-based.md aspnetcore/razor-pages/security/authorization/resource-based
aspnetcore/release-notes/aspnetcore-5.0.md aspnetcore/release-notes/aspnetcore-5.0
aspnetcore/security/authorization/custom-authorization-policies-with-iauthorizationrequirementdata.md aspnetcore/security/authorization/custom-authorization-policies-with-iauthorizationrequirementdata
aspnetcore/security/authorization/customizingauthorizationmiddlewareresponse.md aspnetcore/security/authorization/customizingauthorizationmiddlewareresponse
aspnetcore/security/authorization/dependencyinjection.md aspnetcore/security/authorization/dependencyinjection
aspnetcore/security/authorization/iauthorizationpolicyprovider.md aspnetcore/security/authorization/iauthorizationpolicyprovider
aspnetcore/security/authorization/policies.md aspnetcore/security/authorization/policies
aspnetcore/security/authorization/resource-based.md aspnetcore/security/authorization/resource-based
aspnetcore/security/how-to-choose-identity-solution.md aspnetcore/security/how-to-choose-identity-solution
aspnetcore/toc.yml aspnetcore/toc

@guardrex guardrex self-assigned this Jun 5, 2026
@guardrex
guardrex marked this pull request as ready for review July 10, 2026 14:41
@guardrex
guardrex requested a review from Copilot July 10, 2026 15:02

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR modernizes and restructures the policy-based authorization documentation by shifting MVC and Razor Pages–specific guidance into their own new articles and refocusing the main article on Blazor-oriented examples, while also updating related cross-references and Entra ID links across the docs set.

Changes:

  • Overhauls security/authorization/policies.md to use Razor component examples and updated samples (including a new external-service sample section).
  • Adds new companion articles for MVC and Razor Pages policy-based authorization and wires them into aspnetcore/toc.yml.
  • Updates multiple related docs to point to the new anchors/pages and refreshes Microsoft Entra ID links + ms.date metadata.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
aspnetcore/toc.yml Adds TOC entries for the new MVC and Razor Pages policy-based authorization articles.
aspnetcore/security/how-to-choose-identity-solution.md Updates Entra link + ms.date metadata.
aspnetcore/security/authorization/resource-based.md Updates xref fragments and sample namespace/path text to match the new policies doc structure.
aspnetcore/security/authorization/policies/samples/stubs/copy_of_IAuthorizationService.cs Removes copied framework source stub previously used for an include snippet.
aspnetcore/security/authorization/policies/includes/policies5.md Removes pre-6.0 include content that was previously injected into the policies article.
aspnetcore/security/authorization/policies.md Major rewrite: policy concepts + Blazor-focused examples + new external-service sample walkthrough.
aspnetcore/security/authorization/iauthorizationpolicyprovider.md Updates xref fragments + ms.date.
aspnetcore/security/authorization/dependencyinjection.md Updates xref fragments + ms.date.
aspnetcore/security/authorization/customizingauthorizationmiddlewareresponse.md Updates ms.date.
aspnetcore/security/authorization/custom-authorization-policies-with-iauthorizationrequirementdata.md Replaces hard-coded user values with placeholders in decoded JWT example.
aspnetcore/release-notes/aspnetcore-5.0.md Updates Entra link + ms.date.
aspnetcore/razor-pages/security/authorization/resource-based.md Updates xref fragment to new policies doc anchor.
aspnetcore/razor-pages/security/authorization/policies.md New Razor Pages–specific policy-based authorization article.
aspnetcore/mvc/security/authorization/resource-based.md Updates xref fragment to new policies doc anchor.
aspnetcore/mvc/security/authorization/policies.md New MVC-specific policy-based authorization article (including MVC handler Resource guidance).
aspnetcore/migration/70-to-80.md Updates xref to point to the new MVC policies article section.
aspnetcore/migration/22-to-30.md Updates xrefs to the new policies anchor/article for handler resource guidance.

Comment thread aspnetcore/security/authorization/policies.md
Comment thread aspnetcore/security/authorization/policies.md Outdated
Comment thread aspnetcore/security/authorization/policies.md Outdated
Comment thread aspnetcore/security/authorization/policies.md Outdated
Comment thread aspnetcore/security/authorization/policies.md Outdated
Comment thread aspnetcore/security/authorization/policies.md
Comment thread aspnetcore/security/how-to-choose-identity-solution.md Outdated
Comment thread aspnetcore/security/authorization/policies.md Outdated
guardrex and others added 3 commits July 10, 2026 11:33
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@guardrex
guardrex requested a review from tdykstra July 10, 2026 15:40
@guardrex

Copy link
Copy Markdown
Collaborator Author

@tdykstra ... Pinging again for review.

@tdykstra tdykstra left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great!

I'm approving it but be sure to look at all the comments I made before merging it. 😄

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ms.custom: mvc

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❓... Should I open an issue to remove "mvc" from ms.custom metadata across all Blazor node articles?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can do that; I wouldn't consider it a high priority though.

ms.date: 07/10/2026
uid: security/authorization/authorizationmiddlewareresulthandler
---
# Customize the behavior of `AuthorizationMiddleware`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# Customize the behavior of `AuthorizationMiddleware`
# Customize the behavior of authorization middleware

Comment on lines +18 to +19
* Creating requirements.
* Registering and applying policies.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To avoid gerunds:

Suggested change
* Creating requirements.
* Registering and applying policies.
* How to create requirements.
* How to register and apply policies.

In practice, a policy is applied with `[Authorize(Policy = "...")]` (Razor components, pages, and controllers) or `RequireAuthorization(...)` (endpoints), and the framework uses handlers to evaluate the requirements behind a policy. <xref:Microsoft.AspNetCore.Authorization.IAuthorizationPolicyProvider> (<xref:security/authorization/iauthorizationpolicyprovider> documentation) generates policies dynamically instead of registering them at app startup.

In the preceding example, an "AtLeast21" policy is created. It has a single requirement&mdash;that of a minimum age, which is supplied as a parameter to the requirement.
[Role-based authorization](xref:security/authorization/roles) and [claim-based authorization](xref:security/authorization/claims) use a requirement, a requirement handler, and a preconfigured authorization policy. These building blocks support the expression of authorization evaluations in code.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
[Role-based authorization](xref:security/authorization/roles) and [claim-based authorization](xref:security/authorization/claims) use a requirement, a requirement handler, and a preconfigured authorization policy. These building blocks support the expression of authorization evaluations in code.
[Role-based authorization](xref:security/authorization/roles) and [claims-based authorization](xref:security/authorization/claims) use a requirement, a requirement handler, and a preconfigured authorization policy. These building blocks support the expression of authorization evaluations in code.

[Role-based authorization](xref:security/authorization/roles) and [claim-based authorization](xref:security/authorization/claims) use a requirement, a requirement handler, and a preconfigured authorization policy. These building blocks support the expression of authorization evaluations in code.

## IAuthorizationService
This article uses Razor component examples and focuses on [Blazor](xref:blazor/index) authorization scenarios for ASP.NET Core 3.1 or later. For Razor Pages and MVC guidance, which apply to all releases of ASP.NET Core, see the following resources after reading this article:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This article uses Razor component examples and focuses on [Blazor](xref:blazor/index) authorization scenarios for ASP.NET Core 3.1 or later. For Razor Pages and MVC guidance, which apply to all releases of ASP.NET Core, see the following resources after reading this article:
This article uses Razor component examples and focuses on [Blazor](xref:blazor/index) authorization scenarios for ASP.NET Core 3.1 or later. For Razor Pages and MVC guidance that applies to all releases of ASP.NET Core, see the following resources after reading this article:

policy => policy.RequireClaim("Permission", "CanViewPage", "CanViewAnything")));
:::moniker range=">= aspnetcore-7.0"

A policy is registered as part of the authorization service configuration with <xref:Microsoft.AspNetCore.Authorization.AuthorizationBuilder.AddPolicy%2A?displayProperty=nameWithType> in the app's `Program` file. In the following example, the `AtLeast21` policy is created with a single requirement of a minimum age (`MinimumAgeRequirement`) and setting the minimum age to 21 years old:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
A policy is registered as part of the authorization service configuration with <xref:Microsoft.AspNetCore.Authorization.AuthorizationBuilder.AddPolicy%2A?displayProperty=nameWithType> in the app's `Program` file. In the following example, the `AtLeast21` policy is created with a single requirement of a minimum age (`MinimumAgeRequirement`) and setting the minimum age to 21 years old:
A policy is registered as part of the authorization service configuration in the app's `Program` file, by calling <xref:Microsoft.AspNetCore.Authorization.AuthorizationBuilder.AddPolicy%2A?displayProperty=nameWithType>. The following example creates an `AtLeast21` policy with a single requirement of a minimum age, and it sets the minimum age to 21 years old.

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

<a name="apply-policies-to-mvc-controllers"></a>
A policy is registered as part of the authorization service configuration with <xref:Microsoft.AspNetCore.Authorization.AuthorizationOptions.AddPolicy%2A?displayProperty=nameWithType> in the app's `Program` file. In the following example, the `AtLeast21` policy is created with a single requirement of a minimum age (`MinimumAgeRequirement`) and setting the minimum age to 21 years old:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
A policy is registered as part of the authorization service configuration with <xref:Microsoft.AspNetCore.Authorization.AuthorizationOptions.AddPolicy%2A?displayProperty=nameWithType> in the app's `Program` file. In the following example, the `AtLeast21` policy is created with a single requirement of a minimum age (`MinimumAgeRequirement`) and setting the minimum age to 21 years old:
A policy is registered as part of the authorization service configuration in the app's `Program` file, by calling <xref:Microsoft.AspNetCore.Authorization.AuthorizationBuilder.AddPolicy%2A?displayProperty=nameWithType>. The following example creates an `AtLeast21` policy with a single requirement of a minimum age, and it sets the minimum age to 21 years old:

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

:::code language="csharp" source="~/security/authorization/policies/samples/6.0/AuthorizationPoliciesSample/Controllers/AtLeast21Controller.cs" id="snippet" highlight="1":::
A policy is registered as part of the authorization service configuration with <xref:Microsoft.AspNetCore.Authorization.AuthorizationOptions.AddPolicy%2A?displayProperty=nameWithType> in `Startup.ConfigureServices` (`Startup.cs`). In the following example, the `AtLeast21` policy is created with a single requirement of a minimum age (`MinimumAgeRequirement`) and setting the minimum age to 21 years old:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
A policy is registered as part of the authorization service configuration with <xref:Microsoft.AspNetCore.Authorization.AuthorizationOptions.AddPolicy%2A?displayProperty=nameWithType> in `Startup.ConfigureServices` (`Startup.cs`). In the following example, the `AtLeast21` policy is created with a single requirement of a minimum age (`MinimumAgeRequirement`) and setting the minimum age to 21 years old:
A policy is registered as part of the authorization service configuration in `Startup.ConfigureServices` (`Startup.cs`), by calling <xref:Microsoft.AspNetCore.Authorization.AuthorizationBuilder.AddPolicy%2A?displayProperty=nameWithType>. The following example creates an `AtLeast21` policy with a single requirement of a minimum age, and it sets the minimum age to 21 years old:


### Configure the sample

The following demonstration relies on using the [NSwag (Swagger/OpenAPI)](https://github.com/RicoSuter/NSwag) or [cURL](https://curl.se/) in a command shell.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The following demonstration relies on using the [NSwag (Swagger/OpenAPI)](https://github.com/RicoSuter/NSwag) or [cURL](https://curl.se/) in a command shell.
The following demonstration relies on using [NSwag (Swagger/OpenAPI)](https://github.com/RicoSuter/NSwag) or [cURL](https://curl.se/) in a command shell.

```

* Open the [ContosoAPI.collection.json](https://github.com/dotnet/AspNetCore.Docs.Samples/blob/main/samples/aspnetcore-authz-with-ext-authz-service/ContosoAPI.collection.json) file and configure an environment with the following:
You can add breakpoints in the `Contoso.Security.API.SecurityPolicyController` and observe the passed client ID (`appid`) is used to assert whether it is allowed to obtain weather data.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
You can add breakpoints in the `Contoso.Security.API.SecurityPolicyController` and observe the passed client ID (`appid`) is used to assert whether it is allowed to obtain weather data.
You can add breakpoints in the `Contoso.Security.API.SecurityPolicyController` and see that the passed client ID (`appid`) is used to assert whether it is allowed to obtain weather data.

@guardrex

Copy link
Copy Markdown
Collaborator Author

Thanks, @tdykstra! ... I'll address of your feedback shortly. I just had one question on removing "mvc" from the Blazor articles' metadata. Should I open an issue to do it everywhere, either only across the Blazor node or everywhere across the doc set?

@tdykstra

Copy link
Copy Markdown
Contributor

Thanks, @tdykstra! ... I'll address of your feedback shortly. I just had one question on removing "mvc" from the Blazor articles' metadata. Should I open an issue to do it everywhere, either only across the Blazor node or everywhere across the doc set?

I addressed this in a comment earlier - I would consider it a very low priority, but it's something that you can do to make things more consistent. I would apply it across the doc set, not just Blazor.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Policy-based auth: Refactor for Blazor

3 participants