Авторизация на основе ролей в ASP.NET Core

При создании удостоверения он может принадлежать одной или нескольким ролям. Например, Трейси может принадлежать и AdministratorUser роли, в то время как Скотт может принадлежать только роли User . Создание и управление этими ролями зависит от резервного хранилища процесса авторизации. Роли предоставляются разработчику через IsInRole метод класса ClaimsPrincipal . AddRoles необходимо добавить в службы ролей.

Хотя роли являются утверждениями, не все утверждения являются ролями. В зависимости от издателя удостоверений роль может быть коллекция пользователей, которые могут применять утверждения для участников группы, а также фактическое утверждение для удостоверения. Однако утверждения должны быть сведениями об отдельном пользователе. Использование ролей для добавления утверждений пользователю может запутать границу между пользователем и их отдельными утверждениями. Эта путаница заключается в том, что шаблоны SPA не предназначены для ролей. Кроме того, для организаций, переносимых из локальной устаревшей системы, распространение ролей в течение многих лет может означать, что утверждение роли может быть слишком большим, чтобы содержаться в маркере, который можно использовать spAs. Сведения о защите spAs см. в статье "Защита Identity серверной части веб-API для spAs".

Добавление служб ролей в Identity

Зарегистрируйте службы Program.cs авторизации на основе ролей, вызвав AddRoles тип роли в конфигурации приложения Identity . Тип роли в следующем примере:IdentityRole

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

Для предыдущего кода требуется Microsoft.AspNetCore.Identity. Пакет пользовательского интерфейса и директива using для Microsoft.AspNetCore.Identity.

Добавление проверка ролей

Проверка авторизации на основе ролей:

  • Являются декларативными и указывают роли, которые текущий пользователь должен быть членом для доступа к запрошенному ресурсу.
  • Применяются к Razor страницам, контроллерам или действиям в контроллере.
  • Не удается применить на Razor уровне обработчика страницы, их необходимо применить к странице.

Например, следующий код ограничивает доступ к любым действиям 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 действию.
  • Доступ к действию может получить ShutDown только члены Administrator роли.

Контроллер может быть заблокирован, но разрешить анонимный, не прошедший проверку подлинности доступ к отдельным действиям:

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

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

Для Razor Страниц [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();

Приведенный выше код разрешает пользователям, принадлежащим к ролям или BackupAdministrator ролям.AdministratorPowerUser

При создании удостоверения он может принадлежать одной или нескольким ролям. Например, Трейси может принадлежать к ролям Администратор istrator и user, а Скотт может принадлежать только роли пользователя. Создание и управление этими ролями зависит от резервного хранилища процесса авторизации. Роли предоставляются разработчику через IsInRole метод класса ClaimsPrincipal .

Мы рекомендуем не использовать роли в качестве утверждений , а не использовать утверждения. При использовании одностраничных приложений (SPAs) см. раздел "Защита Identity серверной части веб-API для spAs".

Добавление проверка ролей

Проверка авторизации на основе ролей:

  • Декларативны.
  • Применяются к Razor страницам, контроллерам или действиям в контроллере.
  • Не удается применить на Razor уровне обработчика страницы, их необходимо применить к странице.

Проверка авторизации на основе ролей указывают, какие роли должен быть членом текущего пользователя для доступа к запрашиваемому ресурсу.

Например, следующий код ограничивает доступ к любым действиям 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 Члены роли или PowerUser роли могут получить доступ к контроллеру и SetTime действию.
  • Доступ к действию может получить ShutDown только члены Administrator роли.

Вы также можете заблокировать контроллер, но разрешить анонимный, не прошедший проверку подлинности доступ к отдельным действиям.

[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"));

В этом примере пользователи, принадлежащие к ролям или BackupAdministrator ролей, авторизуют пользователей.AdministratorPowerUser

Добавление служб ролей в 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();
}