Какой атрибут имеет приоритет: Authorize или AllowAnonymous в ASP.NET Core
Что проверяют
Знаете ли вы, как устроена проверка доступа в ASP.NET Core, а не только правило «анонимный побеждает». Следом обычно спрашивают, что будет, если [AllowAnonymous] стоит на контроллере, а [Authorize] на методе, и как это сочетается с глобальной политикой.
Как отвечать
Коротко: приоритет у [AllowAnonymous], и уровень, на котором стоит атрибут, роли не играет. Дальше объясните механизм:
- метаданные эндпоинта: при endpoint routing оба атрибута становятся метаданными эндпоинта.
AuthorizationMiddlewareнаходитIAllowAnonymousи пропускает авторизацию целиком, все[Authorize]на этом эндпоинте игнорируются; - уровень не важен:
[AllowAnonymous]на контроллере отключает проверку для всех его действий, даже если на методе стоит[Authorize(Roles = "Admin")]. Вернуть проверку для отдельного метода атрибутом[Authorize]не получится; - глобальные политики:
FallbackPolicy,RequireAuthorization()наMapControllers()и глобальныйAuthorizeFilterтоже уступают[AllowAnonymous]. В Minimal API тот же эффект даёт.AllowAnonymous(); - аутентификация остаётся: middleware аутентификации всё равно отработает, и если у запроса есть валидная кука или токен,
Userбудет заполнен. Снимается только требование быть авторизованным.
Полезно добавить, как комбинируется сам [Authorize]: несколько атрибутов подряд работают как «и», все политики должны пройти, а роли через запятую в одном атрибуте работают как «или».
Надёжная схема: закрыть всё через FallbackPolicy с RequireAuthenticatedUser() и явно открывать логин и health check.
Где спотыкаются
Считают, что атрибут на методе «ближе» и поэтому сильнее. Из-за этого [AllowAnonymous], повешенный на контроллер ради одного публичного метода, незаметно открывает весь контроллер.
Путают коды ответа. Неаутентифицированный пользователь получает 401 или редирект на логин при куках, а 403 приходит, когда пользователь известен, но прав не хватает.
Пишут собственный IAuthorizationFilter и забывают, что он сам по себе [AllowAnonymous] не учитывает. Проверку IAllowAnonymous в метаданных нужно делать вручную, иначе фильтр закроет публичные эндпоинты.