0Pricing
C# Academy · Урок

Пользовательские требования авторизации

Создавайте пользовательские требования и обработчики.

«Пользовательские требования авторизации» — бесплатный урок C# Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C# Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C# Academy содержит 4 уроков всего.

Когда встроенных средств недостаточно

Некоторые правила нельзя выразить с помощью RequireRole или RequireClaim — например, «возраст должен быть не менее 18 лет» или «пользователь должен владеть этим ресурсом».

Для этого нужно написать пользовательское требование и обработчик.

// Rule: user must be older than a configurable minimum age

IAuthorizationRequirement

Требование — это маркер, содержащий данные правила. Оно реализует пустой интерфейс IAuthorizationRequirement.

public class MinimumAgeRequirement : IAuthorizationRequirement
{
    public int MinimumAge { get; }
    public MinimumAgeRequirement(int minimumAge) =>
        MinimumAge = minimumAge;
}

AuthorizationHandler

Обработчик содержит логику. Унаследуйте его от AuthorizationHandler<TRequirement> и переопределите HandleRequirementAsync.

public class MinimumAgeHandler
    : AuthorizationHandler<MinimumAgeRequirement>
{
    protected override Task HandleRequirementAsync(
        AuthorizationHandlerContext context,
        MinimumAgeRequirement requirement)
    {
        // logic goes here
        return Task.CompletedTask;
    }
}

Успешное выполнение требования

В обработчике проверьте утверждения пользователя. Если правило выполнено, вызовите context.Succeed(requirement). Если нет, просто вернитесь, не вызывая его.

var dobClaim = context.User.FindFirst("birthdate");
if (dobClaim is null) return Task.CompletedTask;

var dob = DateTime.Parse(dobClaim.Value);
int age = DateTime.UtcNow.Year - dob.Year;
if (dob > DateTime.UtcNow.AddYears(-age)) age--;

if (age >= requirement.MinimumAge)
    context.Succeed(requirement);

return Task.CompletedTask;

Вызывайте Succeed, а не Fail

Предпочтительно вызывать Succeed, когда требование выполнено, и ничего не делать в противном случае. Вызывайте context.Fail() только в том случае, если хотите гарантировать отказ независимо от других обработчиков того же требования.

// Soft: let other handlers also try
if (ok) context.Succeed(requirement);

// Hard: force failure no matter what
if (blocked) context.Fail();

Регистрация обработчика

Зарегистрируйте обработчики в DI как IAuthorizationHandler. Обычно они имеют время жизни singleton, если не зависят от сервисов с ограниченной областью действия.

builder.Services.AddSingleton<
    IAuthorizationHandler, MinimumAgeHandler>();

Добавление требования в политику

Добавьте требование в именованную политику с помощью AddRequirements (или Requirements.Add). Обработчик автоматически сопоставляется по типу.

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("AtLeast18", policy =>
        policy.AddRequirements(new MinimumAgeRequirement(18)));
});

Использование политики

Применяйте её так же, как любую другую именованную политику.

[Authorize(Policy = "AtLeast18")]
[HttpGet("age-restricted")]
public IActionResult Restricted() => Ok();

Авторизация на основе ресурса

Чтобы авторизовать доступ к конкретному экземпляру (например, «изменять документ может только его владелец»), используйте перегрузку с ресурсом. Ресурс передаётся в контекст обработчика.

public class OwnerHandler
    : AuthorizationHandler<OwnerRequirement, Document>
{
    protected override Task HandleRequirementAsync(
        AuthorizationHandlerContext context,
        OwnerRequirement requirement,
        Document resource)
    {
        var userId = context.User.FindFirstValue(
            ClaimTypes.NameIdentifier);
        if (resource.OwnerId.ToString() == userId)
            context.Succeed(requirement);
        return Task.CompletedTask;
    }
}

Вызов IAuthorizationService

Проверки на основе ресурса выполняются императивно внутри действия через внедрённый IAuthorizationService.

public async Task<IActionResult> Edit(int id)
{
    var doc = await _db.Documents.FindAsync(id);
    var result = await _authz.AuthorizeAsync(
        User, doc, "DocumentOwner");
    if (!result.Succeeded) return Forbid();
    return Ok(doc);
}

Несколько обработчиков для одного требования

У требования может быть несколько обработчиков; если успешно выполняется любой обработчик, требование считается выполненным. Это позволяет аккуратно моделировать условия OR (если только обработчик не вызывает Fail).

// e.g. allow if owner OR if admin role
services.AddSingleton<IAuthorizationHandler, OwnerHandler>();
services.AddSingleton<IAuthorizationHandler, AdminOverrideHandler>();

Быстрая проверка

Проверьте, насколько хорошо вы понимаете работу обработчиков.

Итоги

Вы создали пользовательскую авторизацию:

  • IAuthorizationRequirement хранит данные правила.
  • AuthorizationHandler<T> содержит логику и вызывает Succeed.
  • Зарегистрируйте обработчик как IAuthorizationHandler и добавьте требование в политику.
  • Обработчики авторизации на основе ресурса и IAuthorizationService авторизуют доступ к конкретным экземплярам.

На этом курс по авторизации завершён.

Часто задаваемые вопросы

Урок «Пользовательские требования авторизации» бесплатный?

Да — полный текст урока «Пользовательские требования авторизации» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C# Academy, подпишись на CoddyKit PRO. Курс C# Academy содержит 4 уроков всего.

Чему я научусь в уроке «Пользовательские требования авторизации»?

Создавайте пользовательские требования и обработчики. Ты практикуешь C# Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать C# Academy?

Предыдущий опыт не требуется. C# Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Пользовательские требования авторизации»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке C# Academy?

Да. Каждый урок C# Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Авторизация на основе ролей
  2. Авторизация на основе утверждений
  3. Авторизация на основе политик
  4. Пользовательские требования авторизации
← Назад к C# Academy