Back to Aspnetcore

Asp0026

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

latest3.1 KB
Original Source

ASP0026: Analyzer to warn when [Authorize] is overridden by [AllowAnonymous] from "farther away"

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.

csharp
[AllowAnonymous]
public class MyController
{
    [Authorize] // Overridden by the [AllowAnonymous] attribute on the class
    public IActionResult Private() => null;
}
csharp
[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;
}
csharp
[AllowAnonymous]
[Authorize] // Overridden by the preceding [AllowAnonymous]
public class MyControllerMultiple : ControllerBase
{
}

In .NET 9 Preview 6, we've introduced an analyzer that will highlight instances like these where a closer [Authorize] attribute gets overridden by an [AllowAnonymous] attribute that is farther away from an MVC action. The warning points to the overridden [Authorize] attribute with the following message:

ASP0026 [Authorize] overridden by [AllowAnonymous] from farther away

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.

csharp
[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;
}