Ограничение Доступа к Методу Действия в ASP.NET Core MVC. Окончание
Начало
Продолжение
Использование обработчиков авторизации
Обработчик авторизации — это реализация IAuthorizationHandler, в виде абстрактного класса AuthorizationHandler<TRequirement>, который принимает требование в качестве параметра. Внутри его метода HandleRequirementAsync мы можем реализовать любую логику, передавая требование в качестве параметра:
public record DayOfWeekRequirement(DayOfWeek Day)
: IAuthorizationRequirement
{
}
Маркерный интерфейс IAuthorizationRequirement не определяет методов. Мы можем добавить свойства в нашу реализацию требования, если хотим передавать данные обработчику.
Подключаем требование к обработчику:
public class DayOfWeekAuthHandler
: AuthorizationHandler<DayOfWeekRequirement>
{
protected override Task HandleRequirementAsync(
AuthorizationHandlerContext ctx,
DayOfWeekRequirement req)
{
if (DateTime.Today.DayOfWeek == req.Day)
ctx.Succeed(req);
else
ctx.Fail(new AuthorizationFailureReason(this, "Неправильный день недели"));
return Task.CompletedTask;
}
}
Простой пример выше, принимает в качестве параметра только день недели, но вариантов ограничений бесконечное множество:
- по IP,
- по наличию/отсутствию cookie,
- по заголовкам запроса…
Внутри HandleRequirementAsync запрос либо завершается неудачей (Fail), либо успехом (Succeed). Если зарегистрировано много обработчиков, все они должны успешно завершиться для получения разрешения на доступ к конечной точке. Для всех обработчиков вызывается один и тот же экземпляр параметра AuthorizationHandlerContext, и оттуда можно проверить:
- текущего аутентифицированного пользователя (User),
- контекст (Resource),
- текущий статус запроса (HasFailed, HasSucceeded),
- обработанные требования (Requirements)
- ожидающие обработки требования (PendingRequirements),
- причины отказа (FailureReasons).
Обработчики необходимо зарегистрировать в DI. ASP.NET Core находит соответствующий обработчик, проверяя переданное требование:
builder.Services
.AddSingleton<IAuthorizationHandler, DayOfWeekAuthHandler>();
Мы должны добавить требования в именованную политику:
builder.Services.AddAuthorizationBuilder()
.AddPolicy("DayOfWeekPolicy", p =>
{
p.Requirements.Add(new DayOfWeekRequirement(DayOfWeek.Saturday));
p.Requirements.Add(new DayOfWeekRequirement(DayOfWeek.Sunday));
});
Теперь мы можем добавить атрибут [Authorize], который ссылается на новую политику:
[Authorize(Policy = "DayOfWeekPolicy")]
public IActionResult Index() { … }
Сравнение альтернатив
С [Authorize] мы можем использовать только политики или роли. Определение политики обеспечивает гораздо большую гибкость, поскольку мы можем указать именно то, что нужно, и это можно изменить в любое время. Тем не менее, обработчики авторизации — более отказоустойчивое и универсальное решение, позволяющее инкапсулировать несколько условий с параметрами, а также использовать DI.
Источник: https://developmentwithadot.blogspot.com/2025/10/restricting-access-to-action-method-in.html