ASP.NET Core 中基于角色的授权Role-based authorization in ASP.NET Core

本文内容

创建标识时,它可能属于一个或多个角色。例如,Tracy 可能属于管理员角色和用户角色,但 Scott 可能只属于用户角色。如何创建和管理这些角色取决于授权过程的后备存储。角色通过ClaimsPrincipal类的IsInRole方法向开发人员公开。

添加角色检查Adding role checks

基于角色的授权检查是声明性—开发人员将其嵌入到代码中,针对控制器或控制器中的操作,指定当前用户必须是其成员的角色才能访问请求的资源。

例如,以下代码将对 AdministrationController 上的任何操作的访问权限限制为作为 Administrator 角色成员的用户:

  1. [Authorize(Roles = "Administrator")]
  2. public class AdministrationController : Controller
  3. {
  4. }

可以将多个角色指定为逗号分隔列表:

  1. [Authorize(Roles = "HRManager,Finance")]
  2. public class SalaryController : Controller
  3. {
  4. }

只有作为 HRManager 角色成员的用户或 Finance 角色的成员才能访问此控制器。

如果应用多个属性,则访问用户必须是所有指定角色的成员;下面的示例要求用户必须同时是 PowerUserControlPanelUser 角色的成员。

  1. [Authorize(Roles = "PowerUser")]
  2. [Authorize(Roles = "ControlPanelUser")]
  3. public class ControlPanelController : Controller
  4. {
  5. }

您可以通过在操作级别应用其他角色授权属性来进一步限制访问权限:

  1. [Authorize(Roles = "Administrator, PowerUser")]
  2. public class ControlPanelController : Controller
  3. {
  4. public ActionResult SetTime()
  5. {
  6. }
  7. [Authorize(Roles = "Administrator")]
  8. public ActionResult ShutDown()
  9. {
  10. }
  11. }

在前面的代码片段中,Administrator 角色或 PowerUser 角色的成员可以访问控制器和 SetTime 操作,但只有 Administrator 角色的成员才能访问 ShutDown 操作。

你还可以锁定控制器,但允许对单个操作进行匿名、未经身份验证的访问。

  1. [Authorize]
  2. public class ControlPanelController : Controller
  3. {
  4. public ActionResult SetTime()
  5. {
  6. }
  7. [AllowAnonymous]
  8. public ActionResult Login()
  9. {
  10. }
  11. }

对于 Razor Pages,可以通过以下任一方法应用 AuthorizeAttribute

  • 使用约定,或
  • AuthorizeAttribute 应用到 PageModel 实例:
  1. [Authorize(Policy = "RequireAdministratorRole")]
  2. public class UpdateModel : PageModel
  3. {
  4. public ActionResult OnPost()
  5. {
  6. }
  7. }

重要

筛选器属性(包括 AuthorizeAttribute)只能应用于 PageModel,而不能应用于特定页面处理程序方法。

基于策略的角色检查Policy based role checks

还可以使用新策略语法来表示角色要求,开发人员可在其中将在启动时作为授权服务配置的一部分注册策略。这通常出现在Startup.cs文件 ConfigureServices() 中。

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. services.AddControllersWithViews();
  4. services.AddRazorPages();
  5. services.AddAuthorization(options =>
  6. {
  7. options.AddPolicy("RequireAdministratorRole",
  8. policy => policy.RequireRole("Administrator"));
  9. });
  10. }
  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. services.AddMvc();
  4. services.AddAuthorization(options =>
  5. {
  6. options.AddPolicy("RequireAdministratorRole",
  7. policy => policy.RequireRole("Administrator"));
  8. });
  9. }

使用 AuthorizeAttribute 属性上的 Policy 属性应用策略:

  1. [Authorize(Policy = "RequireAdministratorRole")]
  2. public IActionResult Shutdown()
  3. {
  4. return View();
  5. }

如果要在某个要求中指定多个允许的角色,则可以将它们指定为 RequireRole 方法的参数:

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

此示例授权属于 AdministratorPowerUserBackupAdministrator 角色的用户。

将角色服务添加到标识Add Role services to Identity

追加AddRoles以添加角色服务:

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. services.AddDbContext<ApplicationDbContext>(options =>
  4. options.UseSqlServer(
  5. Configuration.GetConnectionString("DefaultConnection")));
  6. services.AddDefaultIdentity<IdentityUser>()
  7. .AddRoles<IdentityRole>()
  8. .AddEntityFrameworkStores<ApplicationDbContext>();
  9. services.AddControllersWithViews();
  10. services.AddRazorPages();
  11. }
  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. services.AddDbContext<ApplicationDbContext>(options =>
  4. options.UseSqlServer(
  5. Configuration.GetConnectionString("DefaultConnection")));
  6. services.AddDefaultIdentity<IdentityUser>()
  7. .AddRoles<IdentityRole>()
  8. .AddDefaultUI(UIFramework.Bootstrap4)
  9. .AddEntityFrameworkStores<ApplicationDbContext>();
  10. services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
  11. }