Получить доступ

У пользователя есть authority "ROLE_ADMIN". Какое выражение в @PreAuthorize сработает?

MiddleSpring Security
Ещё спрашивают так:
  • Почему hasRole("ROLE_ADMIN") не работает?
Коротко

hasRole('ADMIN') сам добавляет префикс ROLE_ и сравнивает с authority ROLE_ADMIN; hasAuthority('ROLE_ADMIN') сравнивает строку буквально. Оба сработают; hasRole('ROLE_ADMIN') — нет (с Spring Security 6 даже ошибка).

  • Роли — грубые группы, authorities — тонкие права (orders:write)
  • Из JWT scope приходят как SCOPE_xxx
  • Префикс настраивается GrantedAuthorityDefaults

А ещё Права проверять через hasAuthority — меньше путаницы

Так подсказку видит пользователь sotto на живом собеседовании — за пару секунд, пока вы думаете вслух.

Подробно

Это источник постоянной путаницы, особенно при переходе на JWT, где список прав приходит из токена. Правило простое: hasRole('X') проверяет наличие authority 'ROLE_X', а hasAuthority('X') ищет ровно 'X'. Поэтому если в токене лежит 'ADMIN' без префикса, hasRole('ADMIN') не сработает — нужно либо hasAuthority('ADMIN'), либо настроить конвертер, добавляющий префикс при разборе токена. Заодно стоит помнить, что method security требует включения через @EnableMethodSecurity и работает через прокси, а значит подвержена той же проблеме self-invocation, что и @Transactional.

Что хотят услышать

  • Различие и префикс.
  • Роли против прав.

Частые ошибки

  • Писать hasRole('ROLE_ADMIN') — получится проверка на ROLE_ROLE_ADMIN.
  • Забыть настроить конвертер прав при переходе на JWT.

Проверьте себя

Один верный вариант. Подумайте, потом откройте ответ.

Показать варианты и ответ
  • ✓hasRole('ADMIN') — префикс ROLE_ подставляется автоматически; эквивалентно hasAuthority('ROLE_ADMIN')
  • ✗hasAuthority('ADMIN') — authority сравнивается как есть
  • ✗hasRole('ROLE_ADMIN') — нужно указывать полное имя
  • ✗Оба варианта hasRole('ADMIN') и hasAuthority('ADMIN') сработают одинаково

Что спросят дальше

  • Как настроить извлечение прав из claim в JWT?
  • Почему @PreAuthorize не срабатывает при вызове метода внутри того же класса?

Разбор темы

Связанные вопросы

Закрытая бета

Подсказки на собеседовании — в реальном времени

sotto слышит вопрос интервьюера и показывает короткий ответ и план, как в блоке «Коротко». Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем