ASP.NET Core 中的角色型授權
建立身分識別時,它可能屬於一或多個角色。 例如,Tracy 可能屬於 Administrator
和 User
角色,而 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 套件和適用於 using
的 Microsoft.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
角色成員的使用者存取。
在套用多個屬性時,存取使用者必須是指定之所有角色的成員。 下列範例要求使用者必須同時是 PowerUser
和ControlPanelUser
角色的成員:
[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]
套用至PageModel
執行個體:
[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();
上述程式碼會授權屬於 Administrator
、PowerUser
或 BackupAdministrator
角色的使用者。
建立身分識別時,它可能屬於一或多個角色。 例如,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
。
如果您套用多個屬性,則存取使用者必須是所有指定角色的成員。 下列範例要求使用者必須是 PowerUser
和 ControlPanelUser
角色的成員:
[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
動作。 - 只有
Administrator
和PowerUser
角色的成員才能存取ShutDown
動作。
您也可以鎖定控制器,但允許匿名、未經驗證的個別動作存取。
[Authorize]
public class Control3PanelController : Controller
{
public IActionResult SetTime() =>
Content("[Authorize]");
[AllowAnonymous]
public IActionResult Login() =>
Content("[AllowAnonymous]");
}
針對 Razor Pages,[Authorize]
可以由下列其中一項進行套用:
- 使用慣例,或
- 將
[Authorize]
套用至PageModel
執行個體:
[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"));
此範例會授權屬於 Administrator
、PowerUser
或 BackupAdministrator
角色的使用者。
將角色服務新增至 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();
}