共用方式為


ASP0026:[Authorize] 被「更遠的」[AllowAnonymous] 覆寫

規則識別碼 ASP0026
類別 使用方式
修正是中斷性還是非中斷性的 不間斷

原因

[Authorize] 屬性相比,將 [AllowAnonymous] 屬性放置在「更接近」MVC 動作的位置會覆寫 [AllowAnonymous] 屬性並強制授權,這似乎是直觀的。 不過,不一定是這種情況。 重要的是屬性的相對順序。

備註

[AllowAnonymous] 屬性不會完全停用驗證。 當憑證傳送至端點 [AllowAnonymous]時,端點仍會驗證這些憑證並建立使用者的身分。 此 [AllowAnonymous] 屬性僅表示 不需要驗證 — 只有在未提供認證時,端點才會以匿名方式執行。 此行為對於需要同時適用於已驗證和匿名使用者的端點非常有用。

下列程式碼顯示了 [Authorize] 屬性被較遠的 [AllowAnonymous] 屬性覆寫的範例。

[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
{
}

規則描述

此警告表示屬性 [Authorize] 被來自「上層」的屬性 [AllowAnonymous] 覆蓋。當 [AllowAnonymous] 優先時,端點不需要身份驗證,但仍會接受並處理憑證(如果提供憑證)。 也就是說:

  • 如果要求包含驗證認證,端點會驗證使用者並使其身分可用。
  • 如果請求不包含認證,則端點允許匿名存取。

此行為可能會無意中公開原本需要驗證的端點。

如何修正違規

如果您看到此警告,則所要採取的正確動作取決於屬性背後的意圖。 如果不小心將端點公開給匿名使用者,則應該移除更遠的 [AllowAnonymous] 屬性。 如果 [AllowAnonymous] 屬性是要覆寫更接近的 [Authorize] 屬性,您可以在 [AllowAnonymous] 屬性之後重複 [Authorize] 屬性,以釐清意圖。

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

隱藏警告的時機

此診斷的嚴重性層級為「資訊」。 如果您想要覆寫 [Authorize] 屬性,則可以隱藏警告。 不過,建議您在 [AllowAnonymous] 屬性後面重複 [Authorize] 屬性,讓意圖更為清楚。