Поделиться через


Сведения об авторизации в микрослужбах и веб-приложениях .NET

Подсказка

Это фрагмент из электронной книги «Архитектура микрослужб .NET для контейнеризованных приложений .NET», доступной в документации .NET или в виде бесплатного скачиваемого PDF-файла, который можно прочитать в автономном режиме.

Архитектура микросервисов .NET для приложений .NET в контейнерах, миниатюра обложки электронной книги.

После проверки подлинности ASP.NET Core веб-API требуется авторизация доступа. Этот процесс позволяет службе предоставить интерфейсы API некоторым из пользователей, прошедших аутентификацию, но не всем. Авторизацию можно выполнить на основе ролей пользователей или на основе пользовательской политики, которая может включать проверку утверждений или других эвристики.

Ограничение доступа к маршруту ASP.NET Core MVC так же легко, как применение атрибута Authorization к методу действия (или к классу контроллера, если все действия контроллера требуют авторизации), как показано в следующем примере:

public class AccountController : Controller
{
    public ActionResult Login()
    {
    }

    [Authorize]
    public ActionResult Logout()
    {
    }
}

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

Реализация авторизации на основе ролей

ASP.NET Core Identity имеет встроенную концепцию ролей. Помимо пользователей, ASP.NET Core Identity хранит сведения о разных ролях, используемых приложением, и отслеживает, какие пользователи назначены на какие роли. Эти назначения можно изменять программно с использованием типа RoleManager, который обновляет роли в сохраненном хранилище, и типа UserManager, который может предоставлять или отзывать роли у пользователей.

Если вы выполняете аутентификацию с помощью JWT-бирер токенов, посредством мидлвара для аутентификации JWT-бирер токенов в ASP.NET Core, роли пользователя будут заполняться на основе ролевых утверждений, найденных в токене. Чтобы ограничить доступ к действию или контроллеру MVC пользователям в определенных ролях, можно включить параметр Role в заметку авторизации (атрибут), как показано в следующем фрагменте кода:

[Authorize(Roles = "Administrator, PowerUser")]
public class ControlPanelController : Controller
{
    public ActionResult SetTime()
    {
    }

    [Authorize(Roles = "Administrator")]
    public ActionResult ShutDown()
    {
    }
}

В этом примере только пользователи в ролях Администратора или PowerUser могут получить доступ к API в контроллере ControlPanel (например, при выполнении действия SetTime). API ShutDown также ограничен, чтобы разрешить доступ только пользователям в роли администратора.

Чтобы пользователь был в нескольких ролях, используйте несколько атрибутов авторизации, как показано в следующем примере:

[Authorize(Roles = "Administrator, PowerUser")]
[Authorize(Roles = "RemoteEmployee ")]
[Authorize(Policy = "CustomPolicy")]
public ActionResult API1 ()
{
}

В этом примере для вызова API1 пользователь должен:

  • Находитесь в роли администратора или пользователя с повышенными полномочиями и

  • Находитесь в роли RemoteEmployee и

  • Удовлетворяет пользовательскому обработчику для авторизации CustomPolicy.

Реализация авторизации на основе политик

Пользовательские правила авторизации также можно записать с помощью политик авторизации. В этом разделе представлен обзор. Дополнительные сведения см. в ASP.NET семинаре по авторизации.

Пользовательские политики авторизации регистрируются в методе Startup.ConfigureServices с помощью метода service.AddAuthorization. Этот метод принимает делегат, который настраивает аргумент AuthorizationOptions.

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

    options.AddPolicy("EmployeesOnly", policy =>
        policy.RequireClaim("EmployeeNumber"));

    options.AddPolicy("Over21", policy =>
        policy.Requirements.Add(new MinimumAgeRequirement(21)));
});

Как показано в примере, политики могут быть связаны с различными типами требований. После регистрации политик их можно применить к действию или контроллеру, передав имя политики в качестве аргумента политики атрибута "Авторизовать" (например, [Authorize(Policy="EmployeesOnly")])Политики могут иметь несколько требований, а не только к одному (как показано в этих примерах).

В предыдущем примере первый вызов AddPolicy — это просто альтернативный способ авторизации по роли. Если [Authorize(Policy="AdministratorsOnly")] применяется к API, доступ к нему смогут получить только пользователи роли администратора.

Второй AddPolicy вызов демонстрирует простой способ потребовать наличие конкретного утверждения для пользователя. Метод RequireClaim также при необходимости принимает ожидаемые значения для утверждения. Если заданы значения, требование считается выполненным только в том случае, если у пользователя есть как атрибут правильного типа, так и одно из указанных значений. Если вы используете ПО промежуточного слоя проверки подлинности носителя JWT, все свойства JWT будут доступны в качестве утверждений пользователей.

Наиболее интересная политика, показанная здесь, находится в третьем AddPolicy методе, так как она использует пользовательское требование авторизации. Используя пользовательские требования к авторизации, вы можете иметь большую часть контроля над выполнением авторизации. Для этого необходимо реализовать следующие типы:

  • Тип требований, производный от IAuthorizationRequirement и содержащий поля, указывающие сведения о требовании. В примере это поле возраста для типа примера MinimumAgeRequirement .

  • Обработчик, который реализует AuthorizationHandler<TRequirement>, где T - это тип IAuthorizationRequirement, который может удовлетворить обработчик. Обработчик должен реализовать метод HandleRequirementAsync, который проверяет, выполняет ли указанный контекст, содержащий сведения о пользователе, это требование.

Если пользователь соответствует требованию, вызов context.Succeed указывает, что пользователь авторизован. Если существует несколько способов, которым пользователь может удовлетворить требование авторизации, можно создать несколько обработчиков.

Помимо регистрации пользовательских требований политики с помощью вызовов AddPolicy, необходимо также зарегистрировать обработчики пользовательских требований, используя внедрение зависимостей services.AddTransient<IAuthorizationHandler, MinimumAgeHandler>().

Пример пользовательского требования авторизации и обработчика для проверки возраста пользователя (по утверждению DateOfBirth) доступен в документации по авторизации ASP.NET Core.

Авторизация и минимальные API

ASP.NET поддерживает минимальные API в качестве альтернативы API на основе контроллера. Политики авторизации — это рекомендуемый способ настройки авторизации для минимальных API, как показано в этом примере:

// Program.cs
builder.Services.AddAuthorizationBuilder()
  .AddPolicy("admin_greetings", policy =>
        policy
            .RequireRole("admin")
            .RequireScope("greetings_api"));

// build the app

app.MapGet("/hello", () => "Hello world!")
  .RequireAuthorization("admin_greetings");

Дополнительные ресурсы