Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
105 changes: 105 additions & 0 deletions aspnetcore/mvc/security/authorization/iard.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
---
title: Custom authorization policies with `IAuthorizationRequirementData` in ASP.NET Core MVC
author: tdykstra
description: Learn how to specify requirements associated with the authorization policy in attribute definitions with the IAuthorizationRequirementData interface in ASP.NET Core MVC.
ms.author: tdykstra
monikerRange: '>= aspnetcore-8.0'
ms.date: 03/11/2026
uid: mvc/security/authorization/iard
---
# Custom authorization policies with `IAuthorizationRequirementData` in ASP.NET Core MVC

This article demonstrates the guidance for custom authorization policies with <xref:Microsoft.AspNetCore.Authorization.IAuthorizationRequirementData> in ASP.NET Core MVC. For general guidance on this subject, see <xref:security/authorization/iard>.

## Sample app

The complete MVC sample described in this article is the [`AuthRequirementsData` sample app (`dotnet/AspNetCore.Docs.Samples` GitHub repository)](https://github.com/dotnet/AspNetCore.Docs.Samples/tree/main/security/authorization/AuthRequirementsData) ([how to download](xref:index#how-to-download-a-sample)). The sample app implements a minimum age handler for users, requiring a user to present a birth date claim indicating that they're at least 21 years old.

## Demonstration

Test the sample with [`dotnet user-jwts`](xref:security/authentication/jwt) and curl.

From the project's folder in a command shell, execute the following command to create a JWT bearer token with a birth date claim that makes the user over 21 years old:

```dotnetcli
dotnet user-jwts create --claim http://schemas.xmlsoap.org/ws/2005/05/identity/claims/dateofbirth=1989-01-01
```

The output produces a token after "`Token:`" in the command shell:

```dotnetcli
New JWT saved with ID '{JWT ID}'.
Name: {USER}
Custom Claims: [http://schemas.xmlsoap.org/ws/2005/05/identity/claims/dateofbirth=1989-01-01]

Token: {TOKEN}
```

Set the value of the token (where the `{TOKEN}` placeholder appears in the preceding output) aside for use later.

You can decode the token in an online JWT decoder, such as [`jwt.ms`](https://jwt.ms/) to see its contents, revealing that it contains a `birthdate` claim with the user's birth date:

```json
{
"alg": "HS256",
"typ": "JWT"
}.{
"unique_name": "{USER}",
"sub": "{USER}",
"jti": "{JWT ID}",
"birthdate": "1989-01-01",
"aud": [
"https://localhost:51100",
"http://localhost:51101"
],
"nbf": 1747315312,
"exp": 1755264112,
"iat": 1747315313,
"iss": "dotnet-user-jwts"
}.[Signature]
```

Execute the command again with a `dateofbirth` value that makes the user under the age of 21:

```dotnetcli
dotnet user-jwts create --claim http://schemas.xmlsoap.org/ws/2005/05/identity/claims/dateofbirth=2020-01-01
```

Set the value of second token aside.

Start the app in Visual Studio or with the `dotnet watch` command in the .NET CLI.

In the .NET CLI, execute the following `curl.exe` command to request the `api/greetings/hello` endpoint. Replace the `{TOKEN}` placeholder with the first JWT bearer token that you saved earlier:

```dotnetcli
curl.exe -i -H "Authorization: Bearer {TOKEN}" https://localhost:51100/api/greetings/hello
```

The output indicates success because the user's birth date claim indicates that they're at least 21 years old:

```dotnetcli
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Date: Thu, 15 May 2025 22:58:10 GMT
Server: Kestrel
Transfer-Encoding: chunked

Hello {USER}!
```

Logging indicates that the age requirement was met:

> :::no-loc text="MinimumAgeAuthorizationHandler: Information: Evaluating authorization requirement for age >= 21":::
> :::no-loc text="MinimumAgeAuthorizationHandler: Information: Minimum age authorization requirement 21 satisfied":::

Re-execute the `curl.exe` command with the second token, which indicates the user is under 21 years old. The output indicates that the requirement isn't met. Access to the endpoint is forbidden (status code 403):

```dotnetcli
HTTP/1.1 403 Forbidden
Content-Length: 0
Date: Thu, 15 May 2025 22:58:36 GMT
Server: Kestrel
```

> :::no-loc text="MinimumAgeAuthorizationHandler: Information: Evaluating authorization requirement for age >= 21":::
> :::no-loc text="MinimumAgeAuthorizationHandler: Information: Current user's DateOfBirth claim (2020-01-01) doesn't satisfy the minimum age authorization requirement 21":::
32 changes: 24 additions & 8 deletions aspnetcore/security/authorization/iard.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,24 @@ author: tdykstra
description: Learn how to specify requirements associated with the authorization policy in attribute definitions with the IAuthorizationRequirementData interface.
ms.author: tdykstra
monikerRange: '>= aspnetcore-8.0'
ms.date: 5/16/2025
ms.date: 03/11/2026
uid: security/authorization/iard
---
# Custom authorization policies with `IAuthorizationRequirementData`

Use the <xref:Microsoft.AspNetCore.Authorization.IAuthorizationRequirementData> interface to specify requirements associated with the authorization policy in attribute definitions.

This article uses Blazor Razor component examples and focuses on Blazor authorization scenarios. For a demonstration of the guidance in this article for Razor Pages and MVC, see the <xref:mvc/security/authorization/iard>.

## Sample app

The complete sample described in this article is the [AuthRequirementsData sample app (`dotnet/AspNetCore.Docs.Samples` GitHub repository)](https://github.com/dotnet/AspNetCore.Docs.Samples/tree/main/security/authorization/AuthRequirementsData) ([how to download](xref:blazor/fundamentals/index#sample-apps)). The sample app implements a minimum age handler for users, requiring a user to present a birth date claim indicating that they're at least 21 years old.
The complete Blazor Web App sample described in this article is the [`AuthRequirementsDataBWA` sample app (`dotnet/AspNetCore.Docs.Samples` GitHub repository)](https://github.com/dotnet/AspNetCore.Docs.Samples/tree/main/security/authorization/AuthRequirementsDataBWA) ([how to download](xref:index#how-to-download-a-sample)). The sample app implements a minimum age handler for users, requiring a user to present a birth date claim indicating that they're at least 21 years old.

## Minimum age authorize attribute

The `MinimumAgeAuthorizeAttribute` implementation of <xref:Microsoft.AspNetCore.Authorization.IAuthorizationRequirementData> sets an authorization age:

:::code language="csharp" source="~/../AspNetCore.Docs.Samples/security/authorization/AuthRequirementsData/Authorization/MinimumAgeAuthorizeAttribute.cs":::
:::code language="csharp" source="~/../AspNetCore.Docs.Samples/security/authorization/AuthRequirementsDataBWA/Authorization/MinimumAgeAuthorizeAttribute.cs":::

## Minimum age authorization handler

Expand All @@ -33,7 +35,7 @@ The `HandleRequirementAsync` method:
* Marks the authorization requirement succeeded if the user meets the age requirement.
* Implements logging for demonstration purposes.

:::code language="csharp" source="~/../AspNetCore.Docs.Samples/security/authorization/AuthRequirementsData/Authorization/MinimumAgeAuthorizationHandler.cs":::
:::code language="csharp" source="~/../AspNetCore.Docs.Samples/security/authorization/AuthRequirementsDataBWA/Authorization/MinimumAgeAuthorizationHandler.cs":::

The `MinimumAgeAuthorizationHandler` is registered as a singleton <xref:Microsoft.AspNetCore.Authorization.IAuthorizationHandler> service in the app's `Program` file:

Expand All @@ -42,19 +44,29 @@ builder.Services.AddSingleton<IAuthorizationHandler,
MinimumAgeAuthorizationHandler>();
```

The `GreetingsController` displays the user's name when they satisfy the minimum age policy, using an age of 21 years old with the `[MinimumAgeAuthorize({AGE})]` attribute, where the `{AGE}` placeholder is the age:
A [Minimal API](xref:fundamentals/minimal-apis) endpoint is configured in the app's `Program` file with the <xref:Microsoft.AspNetCore.Builder.AuthorizationEndpointConventionBuilderExtensions.RequireAuthorization%2A> extension method and the `MinimumAgeAuthorizeAttribute`:

```csharp
app.MapGet("/api/greetings/hello", (HttpContext context) =>
{
return $"Hello {context.User.Identity?.Name}!";
}).RequireAuthorization(new MinimumAgeAuthorizeAttribute(21));
```

The endpoint displays the user's name when they satisfy the minimum age policy, using an age of 21 years old with the `MinimumAgeAuthorizeAttribute({AGE})` attribute, where the `{AGE}` placeholder is the age.

:::code language="csharp" source="~/../AspNetCore.Docs.Samples/security/authorization/AuthRequirementsData/Controllers/GreetingsController.cs":::
If the user's birth date claim indicates that they're at least 21 years old, the endpoint displays the greeting string, issuing a 200 (OK) status code. If the user is missing the birth date claim or the claim indicates that they aren't at least 21 years old, the greeting isn't displayed and a 403 (Forbidden) status code is issued.

If the user's birth date claim indicates that they're at least 21 years old, the controller displays the greeting string, issuing a 200 (OK) status code. If the user is missing the birth date claim or the claim indicates that they aren't at least 21 years old, the greeting isn't displayed and a 403 (Forbidden) status code is issued.
> [!NOTE]
> For MVC controller guidance that demonstrates the same behavior, see <xref:mvc/security/authorization/iard>.

JWT bearer authentication services are added in the app's `Program` file:

```csharp
builder.Services.AddAuthentication().AddJwtBearer();
```

The app settings file (`appsettings.json`) configures the audience and issuer for JWT bearer authentication:
The app settings file (`appsettings.Development.json`) configures the audience and issuer for JWT bearer authentication:

```json
"Authentication": {
Expand Down Expand Up @@ -159,3 +171,7 @@ Server: Kestrel

> :::no-loc text="MinimumAgeAuthorizationHandler: Information: Evaluating authorization requirement for age >= 21":::
> :::no-loc text="MinimumAgeAuthorizationHandler: Information: Current user's DateOfBirth claim (2020-01-01) doesn't satisfy the minimum age authorization requirement 21":::

## Additional resources

<xref:mvc/security/authorization/iard>
2 changes: 2 additions & 0 deletions aspnetcore/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,8 @@ items:
items:
- name: Simple authorization
uid: mvc/security/authorization/simple
- name: Custom authorization with IAuthorizationRequirementData
uid: mvc/security/authorization/iard
- name: Blazor
items:
- name: Overview
Expand Down
Loading