共用方式為


ASP.NET Core 中的角色型授權

建立身分識別時,它可能屬於一或多個角色。 例如,Tracy 可能屬於 AdministratorUser 角色,而 Scott 可能只屬於 User 角色。 這些角色的建立和管理方式取決於授權程式的備份存放區。 角色會透過 IsInRole 類別上的 ClaimsPrincipal 方法向開發人員公開。 AddRoles 必須新增至角色服務。

雖然角色是宣告,但並非所有宣告都是角色。 根據身分識別發行者的不同,角色可能是一個用戶集合,這些用戶可以為群組成員申請宣告,也可以是對身分識別的實際宣告。 不過,宣告是個別使用者的相關資訊。 使用角色將宣告新增至使用者,可能會混淆使用者與其個別宣告之間的界限。 這也是 SPA 範本並非圍繞角色所設計的原因。 此外,對於從內部部署舊版系統移轉的組織而言,這些年來角色的激增可能表示角色宣告太大,無法包含在 SPA 可使用的權杖內。 若要保護 SPA,請參閱使用 Identity 來保護 SPA 的 Web API 後端

本文概述 ASP.NET Core MVC 和 Razor 應用程式的角色型授權。 如需有關 Blazor 應用程式的資訊,請參閱 ASP.NET Core Blazor 驗證和授權,以及 ASP.NET Core Blazor WebAssembly 使用 Microsoft Entra ID 群組和角色

將角色服務新增至 Identity

透過使用應用程式的 Program.cs 組態中的角色類型呼叫 AddRoles,在 Identity 中註冊角色型授權服務。 下列範例中的角色類型為 IdentityRole

builder.Services.AddDefaultIdentity<IdentityUser>( ... )
    .AddRoles<IdentityRole>()
    ...

上述程式碼需要 Microsoft.AspNetCore.Identity.UI 套件和適用於 usingMicrosoft.AspNetCore.Identity 指示詞。

新增角色檢查

角色型授權檢查:

  • 是宣告式的,並指定目前使用者必須是其成員才能存取所要求資源的角色。
  • 會套用至控制器內的 Razor Pages、控制器或動作。
  • 無法在 Razor Page 處理常式層級被套用,而必須套用至 Page。

例如,下列程式碼會將 AdministrationController 上的任何動作存取限制為屬於 Administrator 角色成員的使用者:

[Authorize(Roles = "Administrator")]
public class AdministrationController : Controller
{
    public IActionResult Index() =>
        Content("Administrator");
}

多個角色可以指定為逗號分隔清單:

[Authorize(Roles = "HRManager,Finance")]
public class SalaryController : Controller
{
    public IActionResult Payslip() =>
                    Content("HRManager || Finance");
}

SalaryController 僅可由 HRManager 角色Finance 角色成員的使用者存取。

在套用多個屬性時,存取使用者必須是指定之所有角色的成員。 下列範例要求使用者必須同時PowerUserControlPanelUser 角色的成員:

[Authorize(Roles = "PowerUser")]
[Authorize(Roles = "ControlPanelUser")]
public class ControlPanelController : Controller
{
    public IActionResult Index() =>
        Content("PowerUser && ControlPanelUser");
}

在動作層級套用其他角色授權屬性,即可限制動作的存取:

[Authorize(Roles = "Administrator, PowerUser")]
public class ControlAllPanelController : Controller
{
    public IActionResult SetTime() =>
        Content("Administrator || PowerUser");

    [Authorize(Roles = "Administrator")]
    public IActionResult ShutDown() =>
        Content("Administrator only");
}

在上述 ControlAllPanelController 控制器中:

  • Administrator 角色或 PowerUser 角色的成員可以存取控制器和 SetTime 動作。
  • 只有 Administrator 角色的成員可以存取 ShutDown 動作。

控制器可以受到保護,但允許匿名、未經驗證的個別動作存取:

[Authorize]
public class Control3PanelController : Controller
{
    public IActionResult SetTime() =>
        Content("[Authorize]");

    [AllowAnonymous]
    public IActionResult Login() =>
        Content("[AllowAnonymous]");
}

針對 Razor Pages,[Authorize] 可以透過下列其中一項進行套用:

[Authorize(Policy = "RequireAdministratorRole")]
public class UpdateModel : PageModel
{
    public IActionResult OnPost() =>
         Content("OnPost RequireAdministratorRole");
}

重要

篩選屬性 (包括 AuthorizeAttribute) 只能套用至 PageModel,而且無法套用至特定的頁面處理常式方法。

原則型角色檢查

您也可以使用原則語法來表示角色需求,其中開發人員會在應用程式啟動時註冊原則,作為授權服務組態的一部分。 這通常發生在 Program.cs 檔案中:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("RequireAdministratorRole",
         policy => policy.RequireRole("Administrator"));
});

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseAuthentication();
app.UseAuthorization();

app.MapDefaultControllerRoute();
app.MapRazorPages();

app.Run();

原則會使用 Policy 屬性上的 [Authorize] 屬性來套用:

[Authorize(Policy = "RequireAdministratorRole")]
public IActionResult Shutdown()
{
    return View();
}

若要在需求中指定多個允許的角色,請將這些角色指定為 RequireRole 方法的參數:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("ElevatedRights", policy =>
          policy.RequireRole("Administrator", "PowerUser", "BackupAdministrator"));
});

var app = builder.Build();

上述程式碼會授權屬於 AdministratorPowerUserBackupAdministrator 角色的使用者。

建立身分識別時,它可能屬於一或多個角色。 例如,Tracy 可能屬於系統管理員和使用者角色,而 Scott 可能只屬於使用者角色。 這些角色的建立和管理方式取決於授權程式的備份存放區。 角色會透過 IsInRole 類別上的 ClaimsPrincipal 方法向開發人員公開。

我們建議不要使用角色作為宣告,而是使用宣告。 使用單頁應用程式時,請參閱 使用 Identity 來保護 SPA 的 Web API 後端

新增角色檢查

角色型授權檢查:

  • 為宣告式。
  • 會套用至控制器內的 Razor Pages、控制器或動作。
  • 無法在 Razor Page 處理常式層級被套用,而必須套用至 Page。

角色型授權檢查會指定目前使用者必須屬於哪些角色,才能存取要求的資源。

例如,下列程式碼會將 AdministrationController 上的任何動作存取限制為屬於 Administrator 角色成員的使用者:

[Authorize(Roles = "Administrator")]
public class AdministrationController : Controller
{
    public IActionResult Index() =>
        Content("Administrator");
}

多個角色可以指定為逗號分隔清單:

[Authorize(Roles = "HRManager,Finance")]
public class SalaryController : Controller
{
    public IActionResult Payslip() =>
                    Content("HRManager || Finance");
}

只有屬於 SalaryController 角色 HRManager 角色成員的使用者才能存取控制器 Finance

如果您套用多個屬性,則存取使用者必須是所有指定角色的成員。 下列範例要求使用者必須是 PowerUserControlPanelUser 角色的成員:

[Authorize(Roles = "PowerUser")]
[Authorize(Roles = "ControlPanelUser")]
public class ControlPanelController : Controller
{
    public IActionResult Index() =>
        Content("PowerUser && ControlPanelUser");
}

您可以藉由在動作層級套用其他角色授權屬性來進一步限制存取:

[Authorize(Roles = "Administrator, PowerUser")]
public class ControlAllPanelController : Controller
{
    public IActionResult SetTime() =>
        Content("Administrator || PowerUser");

    [Authorize(Roles = "Administrator")]
    public IActionResult ShutDown() =>
        Content("Administrator only");
}

如果在控制器和動作層級套用多個屬性,則所有屬性都必須通過,才能授與存取權:

[Authorize(Roles = "Administrator")]
public class ControlAllPanelController2 : Controller
{
    public IActionResult SetTime() =>
        Content("Administrator only");

    [Authorize(Roles = "PowerUser")]
    public IActionResult ShutDown() =>
        Content("Administrator && PowerUser");
}

在上述 ControlAllPanelController 控制器中:

  • Administrator 角色的成員可以存取控制器和 SetTime 動作。
  • 只有 AdministratorPowerUser 角色的成員才能存取 ShutDown 動作。

您也可以鎖定控制器,但允許匿名、未經驗證的個別動作存取。

[Authorize]
public class Control3PanelController : Controller
{
    public IActionResult SetTime() =>
        Content("[Authorize]");

    [AllowAnonymous]
    public IActionResult Login() =>
        Content("[AllowAnonymous]");
}

針對 Razor Pages,[Authorize] 可以由下列其中一項進行套用:

[Authorize(Policy = "RequireAdministratorRole")]
public class UpdateModel : PageModel
{
    public ActionResult OnPost()
    {
    }
}

重要

篩選屬性 (包括 AuthorizeAttribute) 只能套用至 PageModel,而且無法套用至特定的頁面處理常式方法。

原則型角色檢查

角色需求也可以使用新的原則語法來表示,其中開發人員會在啟動時註冊原則以作為授權服務設定的一部分。 這通常發生在您 ConfigureServices() 檔案的 Startup.cs 中。

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    services.AddRazorPages();

    services.AddAuthorization(options =>
    {
        options.AddPolicy("RequireAdministratorRole",
             policy => policy.RequireRole("Administrator"));
    });
}

原則會使用 Policy 屬性上的 [Authorize] 屬性來進行套用:

[Authorize(Policy = "RequireAdministratorRole")]
public IActionResult Shutdown()
{
    return View();
}

如果您想要在需求中指定多個允許的角色,您可以將這些角色指定為 RequireRole 方法的參數:

options.AddPolicy("ElevatedRights", policy =>
                  policy.RequireRole("Administrator", "PowerUser", "BackupAdministrator"));

此範例會授權屬於 AdministratorPowerUserBackupAdministrator 角色的使用者。

將角色服務新增至 Identity

附加 AddRoles 以新增角色服務:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection")));
    services.AddDefaultIdentity<IdentityUser>()
        .AddRoles<IdentityRole>()
        .AddEntityFrameworkStores<ApplicationDbContext>();

    services.AddControllersWithViews();
    services.AddRazorPages();
}