Политики, роли, claims-based и resource-based авторизация
↑ 3.4 Аутентификация и авторизация · ← Предыдущая · → Следующая
Зачем это на собесе
Проверяется умение выбрать модель доступа: роли, claims, политики или проверка по ресурсу.
Объяснение
| Модель | Пример | Когда |
|---|---|---|
| Role-based | [Authorize(Roles = "Admin")] | простые системы |
| Claims-based | RequireClaim("department", "sales") | атрибуты пользователя |
| Policy-based | RequireAssertion, свои requirements | сложные правила |
| Resource-based | «может ли user изменить этот документ» | владение, ACL |
builder.Services.AddAuthorizationBuilder()
.AddPolicy("Adult", p => p.RequireClaim("age").RequireAssertion(c => int.Parse(c.User.FindFirstValue("age")!) >= 18))
.AddPolicy("CanEditOrders", p => p.Requirements.Add(new EditOrdersRequirement()));
app.MapDelete("/orders/{id}", Delete).RequireAuthorization("CanEditOrders");Resource-based
public class OrderOwnerHandler : AuthorizationHandler<OwnerRequirement, Order>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext ctx, OwnerRequirement req, Order order)
{
if (order.OwnerId == ctx.User.FindFirstValue(ClaimTypes.NameIdentifier)) ctx.Succeed(req);
return Task.CompletedTask;
}
}
var result = await authz.AuthorizeAsync(User, order, new OwnerRequirement());
if (!result.Succeeded) return Forbid();Ресурс нужно сначала загрузить, поэтому проверка выполняется в коде, а не атрибутом.
Нюансы и подводные камни
- IDOR: проверяйте доступ к объекту, а не только роль (
/orders/123чужого пользователя). - Множество requirement-ов в одной политике — AND; несколько handlers одного requirement — OR.
- Фильтруйте выборки по владельцу на уровне запроса (
Where(o => o.OwnerId == userId)). - Проверки прав только на UI не защищают API.
Практика
- Реализуйте политику «владелец или админ».
- Добавьте resource-based handler для заказов и тест на попытку доступа к чужому.
- Настройте fallback policy для всего API.
Вопросы с ответами
Роль или политика?
Роль — грубая группа; политика инкапсулирует правило (роль, claims, ресурс) и гибче.
Что такое IDOR?
Небезопасный прямой доступ к объектам: пользователь меняет идентификатор и получает чужие данные; лечится проверкой владения на сервере.
Когда нужна resource-based авторизация?
Когда решение зависит от конкретного объекта, а не только от пользователя.