From ae3831a188c7a91ae92351442c75e79f71330c9e Mon Sep 17 00:00:00 2001 From: guardrex <1622880+guardrex@users.noreply.github.com> Date: Wed, 11 Mar 2026 17:16:01 -0400 Subject: [PATCH 1/6] Custom auth policies with IARD overhaul --- aspnetcore/mvc/security/authorization/iard.md | 105 ++++++++++++++++++ aspnetcore/security/authorization/iard.md | 32 ++++-- aspnetcore/toc.yml | 2 + 3 files changed, 131 insertions(+), 8 deletions(-) create mode 100644 aspnetcore/mvc/security/authorization/iard.md diff --git a/aspnetcore/mvc/security/authorization/iard.md b/aspnetcore/mvc/security/authorization/iard.md new file mode 100644 index 000000000000..fc5debc5ac8c --- /dev/null +++ b/aspnetcore/mvc/security/authorization/iard.md @@ -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 in ASP.NET Core MVC. For general guidance on this subject, see . + +## 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"::: diff --git a/aspnetcore/security/authorization/iard.md b/aspnetcore/security/authorization/iard.md index 628ee7d9267a..ae6c1bae04ef 100644 --- a/aspnetcore/security/authorization/iard.md +++ b/aspnetcore/security/authorization/iard.md @@ -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 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 . + ## 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 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 @@ -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 service in the app's `Program` file: @@ -42,11 +44,21 @@ builder.Services.AddSingleton(); ``` -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 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 . JWT bearer authentication services are added in the app's `Program` file: @@ -54,7 +66,7 @@ JWT bearer authentication services are added in the app's `Program` file: 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": { @@ -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 + + diff --git a/aspnetcore/toc.yml b/aspnetcore/toc.yml index ca6bef17e1a1..e651730925ca 100644 --- a/aspnetcore/toc.yml +++ b/aspnetcore/toc.yml @@ -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 From ed3a096691efb1baa758e6288b37e4c70ce2afc6 Mon Sep 17 00:00:00 2001 From: guardrex <1622880+guardrex@users.noreply.github.com> Date: Wed, 11 Mar 2026 17:44:36 -0400 Subject: [PATCH 2/6] Updates --- aspnetcore/mvc/security/authorization/iard.md | 5 +++-- aspnetcore/security/authorization/iard.md | 7 ++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/aspnetcore/mvc/security/authorization/iard.md b/aspnetcore/mvc/security/authorization/iard.md index fc5debc5ac8c..108b671b0949 100644 --- a/aspnetcore/mvc/security/authorization/iard.md +++ b/aspnetcore/mvc/security/authorization/iard.md @@ -1,15 +1,16 @@ --- title: Custom authorization policies with `IAuthorizationRequirementData` in ASP.NET Core MVC +ai-usage: ai-assisted 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.author: tdykstra 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 in ASP.NET Core MVC. For general guidance on this subject, see . +This article shows how to use to define custom authorization policies in ASP.NET Core MVC. For general guidance on this subject, see . ## Sample app diff --git a/aspnetcore/security/authorization/iard.md b/aspnetcore/security/authorization/iard.md index ae6c1bae04ef..4a33c515999c 100644 --- a/aspnetcore/security/authorization/iard.md +++ b/aspnetcore/security/authorization/iard.md @@ -1,9 +1,10 @@ --- title: Custom authorization policies with `IAuthorizationRequirementData` +ai-usage: ai-assisted 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.author: tdykstra ms.date: 03/11/2026 uid: security/authorization/iard --- @@ -11,7 +12,7 @@ uid: security/authorization/iard Use the 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 . +This article uses [Minimal API](xref:fundamentals/minimal-apis) endpoint examples and focuses on testing JWT-based authorization. For a demonstration of similar guidance in an MVC app, see the . ## Sample app @@ -53,7 +54,7 @@ app.MapGet("/api/greetings/hello", (HttpContext context) => }).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. +The endpoint displays the user's name when they satisfy the minimum age policy, using an age of 21 years old supplied to a `MinimumAgeAuthorizeAttribute` instance. 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. From 08b8ea092eafd1c291a78029778fee29f72fed76 Mon Sep 17 00:00:00 2001 From: guardrex <1622880+guardrex@users.noreply.github.com> Date: Wed, 11 Mar 2026 18:12:01 -0400 Subject: [PATCH 3/6] Updates --- .openpublishing.redirection.json | 5 +++++ ...on-policies-with-iauthorizationrequirementdata-in-mvc.md} | 0 ...orization-policies-with-iauthorizationrequirementdata.md} | 0 3 files changed, 5 insertions(+) rename aspnetcore/mvc/security/authorization/{iard.md => custom-authorization-policies-with-iauthorizationrequirementdata-in-mvc.md} (100%) rename aspnetcore/security/authorization/{iard.md => custom-authorization-policies-with-iauthorizationrequirementdata.md} (100%) diff --git a/.openpublishing.redirection.json b/.openpublishing.redirection.json index 626e236c38d4..2a7a0b3f09c3 100644 --- a/.openpublishing.redirection.json +++ b/.openpublishing.redirection.json @@ -1673,6 +1673,11 @@ "source_path": "aspnetcore/migration/20_21.md", "redirect_url": "/aspnet/core/migration/20-to-21", "redirect_document_id": false + }, + { + "source_path": "aspnetcore/security/authorization/iard.md", + "redirect_url": "/aspnet/core/security/authorization/custom-authorization-policies-with-iauthorizationrequirementdata", + "redirect_document_id": false } ] } diff --git a/aspnetcore/mvc/security/authorization/iard.md b/aspnetcore/mvc/security/authorization/custom-authorization-policies-with-iauthorizationrequirementdata-in-mvc.md similarity index 100% rename from aspnetcore/mvc/security/authorization/iard.md rename to aspnetcore/mvc/security/authorization/custom-authorization-policies-with-iauthorizationrequirementdata-in-mvc.md diff --git a/aspnetcore/security/authorization/iard.md b/aspnetcore/security/authorization/custom-authorization-policies-with-iauthorizationrequirementdata.md similarity index 100% rename from aspnetcore/security/authorization/iard.md rename to aspnetcore/security/authorization/custom-authorization-policies-with-iauthorizationrequirementdata.md From 6f3ffe47a8b1adf56e92e2853bad55d54cee8376 Mon Sep 17 00:00:00 2001 From: guardrex <1622880+guardrex@users.noreply.github.com> Date: Thu, 12 Mar 2026 09:01:01 -0400 Subject: [PATCH 4/6] Updates --- ...th-iauthorizationrequirementdata-in-mvc.md | 41 +++++++++++++------ ...cies-with-iauthorizationrequirementdata.md | 38 ++++++++++++----- 2 files changed, 56 insertions(+), 23 deletions(-) diff --git a/aspnetcore/mvc/security/authorization/custom-authorization-policies-with-iauthorizationrequirementdata-in-mvc.md b/aspnetcore/mvc/security/authorization/custom-authorization-policies-with-iauthorizationrequirementdata-in-mvc.md index 108b671b0949..4856dfbbd01d 100644 --- a/aspnetcore/mvc/security/authorization/custom-authorization-policies-with-iauthorizationrequirementdata-in-mvc.md +++ b/aspnetcore/mvc/security/authorization/custom-authorization-policies-with-iauthorizationrequirementdata-in-mvc.md @@ -10,11 +10,11 @@ uid: mvc/security/authorization/iard --- # Custom authorization policies with `IAuthorizationRequirementData` in ASP.NET Core MVC -This article shows how to use to define custom authorization policies in ASP.NET Core MVC. For general guidance on this subject, see . +This article provides a demonstration on how to use to define custom authorization policies in ASP.NET Core MVC. For general guidance on this subject, see . ## 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. +The MVC sample for 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 @@ -45,17 +45,14 @@ You can decode the token in an online JWT decoder, such as [`jwt.ms`](https://jw "alg": "HS256", "typ": "JWT" }.{ - "unique_name": "{USER}", - "sub": "{USER}", - "jti": "{JWT ID}", + "unique_name": "guard", + "sub": "guard", + "jti": "5316e1b4", "birthdate": "1989-01-01", - "aud": [ - "https://localhost:51100", - "http://localhost:51101" - ], - "nbf": 1747315312, - "exp": 1755264112, - "iat": 1747315313, + "aud": "https://localhost:51100", + "nbf": 1773320013, + "exp": 1781268813, + "iat": 1773320014, "iss": "dotnet-user-jwts" }.[Signature] ``` @@ -70,7 +67,7 @@ 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: +In a command shell, use the .NET CLI to 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 @@ -90,6 +87,14 @@ 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"::: @@ -102,5 +107,15 @@ Date: Thu, 15 May 2025 22:58:36 GMT Server: Kestrel ``` +Logging indicates that the age requirement wasn't met: + + + > :::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"::: diff --git a/aspnetcore/security/authorization/custom-authorization-policies-with-iauthorizationrequirementdata.md b/aspnetcore/security/authorization/custom-authorization-policies-with-iauthorizationrequirementdata.md index 4a33c515999c..3b69ccff8133 100644 --- a/aspnetcore/security/authorization/custom-authorization-policies-with-iauthorizationrequirementdata.md +++ b/aspnetcore/security/authorization/custom-authorization-policies-with-iauthorizationrequirementdata.md @@ -12,11 +12,11 @@ uid: security/authorization/iard Use the interface to specify requirements associated with the authorization policy in attribute definitions. -This article uses [Minimal API](xref:fundamentals/minimal-apis) endpoint examples and focuses on testing JWT-based authorization. For a demonstration of similar guidance in an MVC app, see the . +This article uses a [Minimal API](xref:fundamentals/minimal-apis) endpoint within the app and focuses on testing JWT-based authorization. For a demonstration of similar guidance in an MVC app with a controller, see the . ## Sample app -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. +The Blazor Web App sample for 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 @@ -113,17 +113,17 @@ You can decode the token in an online JWT decoder, such as [`jwt.ms`](https://jw "alg": "HS256", "typ": "JWT" }.{ - "unique_name": "{USER}", - "sub": "{USER}", - "jti": "{JWT ID}", + "unique_name": "guard", + "sub": "guard", + "jti": "b81dbbdd", "birthdate": "1989-01-01", "aud": [ "https://localhost:51100", - "http://localhost:51101" + "http://localhost:5000" ], - "nbf": 1747315312, - "exp": 1755264112, - "iat": 1747315313, + "nbf": 1773320094, + "exp": 1781268894, + "iat": 1773320095, "iss": "dotnet-user-jwts" }.[Signature] ``` @@ -138,7 +138,7 @@ 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: +In a command shell, use the .NET CLI to 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 @@ -158,6 +158,14 @@ 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"::: @@ -170,6 +178,16 @@ Date: Thu, 15 May 2025 22:58:36 GMT Server: Kestrel ``` +Logging indicates that the age requirement wasn't met: + + + > :::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"::: From 43f5f77d73995448a2ae4440b33b128f07e5debb Mon Sep 17 00:00:00 2001 From: guardrex <1622880+guardrex@users.noreply.github.com> Date: Mon, 16 Mar 2026 08:27:23 -0400 Subject: [PATCH 5/6] Updates --- ...th-iauthorizationrequirementdata-in-mvc.md | 21 ++++++++++++------- ...cies-with-iauthorizationrequirementdata.md | 21 ++++++++++++------- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/aspnetcore/mvc/security/authorization/custom-authorization-policies-with-iauthorizationrequirementdata-in-mvc.md b/aspnetcore/mvc/security/authorization/custom-authorization-policies-with-iauthorizationrequirementdata-in-mvc.md index 4856dfbbd01d..6ad21258b50e 100644 --- a/aspnetcore/mvc/security/authorization/custom-authorization-policies-with-iauthorizationrequirementdata-in-mvc.md +++ b/aspnetcore/mvc/security/authorization/custom-authorization-policies-with-iauthorizationrequirementdata-in-mvc.md @@ -47,12 +47,15 @@ You can decode the token in an online JWT decoder, such as [`jwt.ms`](https://jw }.{ "unique_name": "guard", "sub": "guard", - "jti": "5316e1b4", + "jti": "6cd613ed", "birthdate": "1989-01-01", - "aud": "https://localhost:51100", - "nbf": 1773320013, - "exp": 1781268813, - "iat": 1773320014, + "aud": [ + "https://localhost:5001", + "http://localhost:5000" + ], + "nbf": 1773663513, + "exp": 1781612313, + "iat": 1773663515, "iss": "dotnet-user-jwts" }.[Signature] ``` @@ -65,12 +68,16 @@ dotnet user-jwts create --claim http://schemas.xmlsoap.org/ws/2005/05/identity/c Set the value of second token aside. -Start the app in Visual Studio or with the `dotnet watch` command in the .NET CLI. +Start the app in Visual Studio or with the `dotnet watch` command in a command shell: + +```dotnetcli +dotnet watch +``` In a command shell, use the .NET CLI to 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 +curl.exe -i -H "Authorization: Bearer {TOKEN}" https://localhost:5001/api/greetings/hello ``` The output indicates success because the user's birth date claim indicates that they're at least 21 years old: diff --git a/aspnetcore/security/authorization/custom-authorization-policies-with-iauthorizationrequirementdata.md b/aspnetcore/security/authorization/custom-authorization-policies-with-iauthorizationrequirementdata.md index 3b69ccff8133..b04e2b3fce54 100644 --- a/aspnetcore/security/authorization/custom-authorization-policies-with-iauthorizationrequirementdata.md +++ b/aspnetcore/security/authorization/custom-authorization-policies-with-iauthorizationrequirementdata.md @@ -74,7 +74,8 @@ The app settings file (`appsettings.Development.json`) configures the audience a "Schemes": { "Bearer": { "ValidAudiences": [ - "https://localhost:51100" + "https://localhost:5001", + "http://localhost:5000" ], "ValidIssuer": "dotnet-user-jwts" } @@ -115,15 +116,15 @@ You can decode the token in an online JWT decoder, such as [`jwt.ms`](https://jw }.{ "unique_name": "guard", "sub": "guard", - "jti": "b81dbbdd", + "jti": "6cd613ed", "birthdate": "1989-01-01", "aud": [ - "https://localhost:51100", + "https://localhost:5001", "http://localhost:5000" ], - "nbf": 1773320094, - "exp": 1781268894, - "iat": 1773320095, + "nbf": 1773663513, + "exp": 1781612313, + "iat": 1773663515, "iss": "dotnet-user-jwts" }.[Signature] ``` @@ -136,12 +137,16 @@ dotnet user-jwts create --claim http://schemas.xmlsoap.org/ws/2005/05/identity/c Set the value of second token aside. -Start the app in Visual Studio or with the `dotnet watch` command in the .NET CLI. +Start the app in Visual Studio or with the `dotnet watch` command in a command shell: + +```dotnetcli +dotnet watch +``` In a command shell, use the .NET CLI to 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 +curl.exe -i -H "Authorization: Bearer {TOKEN}" https://localhost:5001/api/greetings/hello ``` The output indicates success because the user's birth date claim indicates that they're at least 21 years old: From df7239fa3e76140a5297e2fbfdcbb00fc5278afb Mon Sep 17 00:00:00 2001 From: guardrex <1622880+guardrex@users.noreply.github.com> Date: Mon, 16 Mar 2026 08:28:48 -0400 Subject: [PATCH 6/6] Updates --- ...zation-policies-with-iauthorizationrequirementdata-in-mvc.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aspnetcore/mvc/security/authorization/custom-authorization-policies-with-iauthorizationrequirementdata-in-mvc.md b/aspnetcore/mvc/security/authorization/custom-authorization-policies-with-iauthorizationrequirementdata-in-mvc.md index 6ad21258b50e..2da55d790a4c 100644 --- a/aspnetcore/mvc/security/authorization/custom-authorization-policies-with-iauthorizationrequirementdata-in-mvc.md +++ b/aspnetcore/mvc/security/authorization/custom-authorization-policies-with-iauthorizationrequirementdata-in-mvc.md @@ -66,7 +66,7 @@ Execute the command again with a `dateofbirth` value that makes the user under t 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. +Set the value of the second token aside. Start the app in Visual Studio or with the `dotnet watch` command in a command shell: