Skip to content

Commit cbf1b59

Browse files
Copilottdykstra
andauthored
Clarify that [AllowAnonymous] allows authentication, not disables it (#36304)
* Initial plan * Clarify ASP0026 warning: AllowAnonymous allows but doesn't require authentication Co-authored-by: tdykstra <[email protected]> --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: tdykstra <[email protected]>
1 parent 0d1ec5b commit cbf1b59

File tree

2 files changed

+23
-7
lines changed

2 files changed

+23
-7
lines changed

aspnetcore/diagnostics/asp0026.md

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
---
22
title: "ASP0026: Analyzer to warn when [Authorize] is overridden by [AllowAnonymous] from 'farther away'"
3-
ms.date: 03/27/2025
4-
description: "Learn about analysis rule ASP0026: [Authorize] is overridden by [AllowAnonymous] from 'farther away'"
3+
ai-usage: ai-assisted
54
author: tdykstra
5+
description: "Learn about analysis rule ASP0026: [Authorize] is overridden by [AllowAnonymous] from 'farther away'"
66
monikerRange: '>= aspnetcore-9.0'
77
ms.author: tdykstra
8+
ms.date: 11/06/2025
89
uid: diagnostics/asp0026
910
---
1011
# ASP0026: `[Authorize]` is overridden by `[AllowAnonymous]` from "farther away"
@@ -19,6 +20,9 @@ uid: diagnostics/asp0026
1920

2021
It seems intuitive that an `[Authorize]` attribute placed "closer" to an MVC action than an `[AllowAnonymous]` attribute would override the `[AllowAnonymous]` attribute and force authorization. However, this is not necessarily the case. What does matter is the relative order of the attributes.
2122

23+
> [!NOTE]
24+
> The `[AllowAnonymous]` attribute doesn't disable authentication entirely. When credentials are sent to an endpoint with `[AllowAnonymous]`, the endpoint still authenticates those credentials and establishes the user's identity. The `[AllowAnonymous]` attribute only means that authentication is **not required**—the endpoint will run as anonymous only when no credentials are provided. This behavior can be useful for endpoints that need to work for both authenticated and anonymous users.
25+
2226
The following code shows examples where a closer `[Authorize]` attribute gets overridden by an `[AllowAnonymous]` attribute that is farther away.
2327

2428
```csharp
@@ -58,7 +62,12 @@ public class MyControllerMultiple : ControllerBase
5862

5963
## Rule description
6064

61-
Warning that an `[Authorize]` attribute is overridden by an `[AllowAnonymous]` attribute from "farther away."
65+
This warning indicates that an `[Authorize]` attribute is overridden by an `[AllowAnonymous]` attribute from "farther away." When `[AllowAnonymous]` takes precedence, the endpoint doesn't require authentication but still accepts and processes credentials if they're provided. This means:
66+
67+
- If a request includes authentication credentials, the endpoint authenticates the user and makes their identity available.
68+
- If a request doesn't include credentials, the endpoint allows anonymous access.
69+
70+
This behavior might unintentionally expose endpoints that were meant to require authentication.
6271

6372
## How to fix violations
6473

@@ -70,8 +79,10 @@ public class MyController
7079
{
7180
// This produces no warning because the second, "closer" [AllowAnonymous]
7281
// clarifies that [Authorize] is intentionally overridden.
73-
// Specifying AuthenticationSchemes can still be useful
74-
// for endpoints that allow but don't require authenticated users.
82+
// Specifying AuthenticationSchemes can be useful for endpoints that
83+
// allow but don't require authenticated users. When credentials are sent,
84+
// they will be authenticated; when no credentials are sent, the endpoint
85+
// allows anonymous access.
7586
[Authorize(AuthenticationSchemes = "Cookies")]
7687
[AllowAnonymous]
7788
public IActionResult Privacy() => null;

aspnetcore/release-notes/aspnetcore-9/includes/asp0026.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
It seems intuitive that an `[Authorize]` attribute placed "closer" to an MVC action than an `[AllowAnonymous]` attribute would override the `[AllowAnonymous]` attribute and force authorization. However, this is not necessarily the case. What does matter is the relative order of the attributes.
44

5+
> [!NOTE]
6+
> The `[AllowAnonymous]` attribute doesn't disable authentication entirely. When credentials are sent to an endpoint with `[AllowAnonymous]`, the endpoint still authenticates those credentials and establishes the user's identity. The `[AllowAnonymous]` attribute only means that authentication is **not required**—the endpoint will run as anonymous only when no credentials are provided. This behavior can be useful for endpoints that need to work for both authenticated and anonymous users.
7+
58
The following code shows examples where a closer `[Authorize]` attribute gets overridden by an `[AllowAnonymous]` attribute that is farther away.
69

710
```csharp
@@ -53,8 +56,10 @@ public class MyController
5356
{
5457
// This produces no warning because the second, "closer" [AllowAnonymous]
5558
// clarifies that [Authorize] is intentionally overridden.
56-
// Specifying AuthenticationSchemes can still be useful
57-
// for endpoints that allow but don't require authenticated users.
59+
// Specifying AuthenticationSchemes can be useful for endpoints that
60+
// allow but don't require authenticated users. When credentials are sent,
61+
// they will be authenticated; when no credentials are sent, the endpoint
62+
// allows anonymous access.
5863
[Authorize(AuthenticationSchemes = "Cookies")]
5964
[AllowAnonymous]
6065
public IActionResult Privacy() => null;

0 commit comments

Comments
 (0)