Пользовательские требования авторизации
Создавайте пользовательские требования и обработчики.
«Пользовательские требования авторизации» — бесплатный урок 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 ageIAuthorizationRequirement
Требование — это маркер, содержащий данные правила. Оно реализует пустой интерфейс 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 — локальная установка не требуется.
Все уроки этого курса
- Авторизация на основе ролей
- Авторизация на основе утверждений
- Авторизация на основе политик
- Пользовательские требования авторизации