Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
ASP0026:
| Value | |
|---|---|
| Rule ID | ASP0026 |
| Category | Usage |
| Fix is breaking or non-breaking | Non-breaking |
Cause
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.
Note
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.
The following code shows examples where a closer [Authorize] attribute gets overridden by an [AllowAnonymous] attribute that is farther away.
[AllowAnonymous]
public class MyController
{
[Authorize] // Overridden by the [AllowAnonymous] attribute on the class
public IActionResult Private() => null;
}
[AllowAnonymous]
public class MyControllerAnon : ControllerBase
{
}
[Authorize] // Overridden by the [AllowAnonymous] attribute on MyControllerAnon
public class MyControllerInherited : MyControllerAnon
{
}
public class MyControllerInherited2 : MyControllerAnon
{
[Authorize] // Overridden by the [AllowAnonymous] attribute on MyControllerAnon
public IActionResult Private() => null;
}
[AllowAnonymous]
[Authorize] // Overridden by the preceding [AllowAnonymous]
public class MyControllerMultiple : ControllerBase
{
}
Rule description
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:
- If a request includes authentication credentials, the endpoint authenticates the user and makes their identity available.
- If a request doesn't include credentials, the endpoint allows anonymous access.
This behavior might unintentionally expose endpoints that were meant to require authentication.
How to fix violations
The correct action to take if you see this warning depends on the intention behind the attributes. The farther away [AllowAnonymous] attribute should be removed if it's unintentionally exposing the endpoint to anonymous users. If the [AllowAnonymous] attribute was intended to override a closer [Authorize] attribute, you can repeat the [AllowAnonymous] attribute after the [Authorize] attribute to clarify the intent.
[AllowAnonymous]
public class MyController
{
// This produces no warning because the second, "closer" [AllowAnonymous]
// clarifies that [Authorize] is intentionally overridden.
// Specifying AuthenticationSchemes can be useful for endpoints that
// allow but don't require authenticated users. When credentials are sent,
// they will be authenticated; when no credentials are sent, the endpoint
// allows anonymous access.
[Authorize(AuthenticationSchemes = "Cookies")]
[AllowAnonymous]
public IActionResult Privacy() => null;
}
When to suppress warnings
The severity level of this diagnostic is Information. You can suppress warnings if your intention is to override the [Authorize] attribute. However, we recommend that you make the intent clear by repeating the [AllowAnonymous] attribute after the [Authorize] attribute.
ASP.NET Core