Основы аутентификации и авторизации
SmartMVC задаёт точки интеграции и жизненный цикл аутентификации и авторизации, но не определяет, где должны храниться пользователи и какой именно токен следует выпускать.
Приложение отвечает за следующее:
- проверяет токен, Cookie или Session;
- загружает пользователя, его роли и разрешения;
- решает, можно ли использовать учётную запись;
- предоставляет собственную реализацию
AuthInterceptor.
SmartMVC со своей стороны:
- определяет, требуется ли аутентификация для текущего метода API;
- извлекает учётные данные из запроса;
- вызывает реализацию аутентификации приложения;
- проверяет аннотации и разрешение на текущий запрос;
- сохраняет данные аутентифицированного пользователя в
CurrentAuth; - очищает эти данные после завершения запроса.
Два режима аутентификации
ANNOTATED
spring.smart.mvc.auth.mode: ANNOTATED
Аутентификация выполняется только для контроллеров и методов с @Auth. Методы API без аннотации остаются открытыми.
Этот режим подходит, если:
- аутентификация постепенно добавляется в существующий проект;
- сервис содержит много открытых методов API;
- важно явно видеть каждый защищённый метод API в коде.
GLOBAL
spring.smart.mvc.auth.mode: GLOBAL
По умолчанию аутентифицируются все методы контроллеров. Исключение составляют только методы с @Anonymous и пути из exclude-paths.
Этот режим подходит для:
- административных систем;
- сервисов, где вход требуется почти для всех операций;
- приложений, выбирающих защиту по умолчанию.
@Auth
Если требуется только вход пользователя:
@Auth
@GetMapping("/profile")
public ProfileView profile() {
// ...
}
Если одновременно нужны роль и именованное разрешение:
@Auth(
roles = "admin",
permissions = "user:read"
)
@GetMapping("/users")
public List<UserView> users() {
// ...
}
@Auth можно разместить на классе, методе или составной аннотации.
@Anonymous
@Anonymous
@PostMapping("/login")
public LoginResponse login(@RequestBody LoginRequest request) {
// ...
}
Для анонимного метода пропускаются аутентификация, авторизация и сохранение данных текущего пользователя. Поэтому при стандартном поведении:
currentAuth.isAuthenticated()возвращаетfalse;currentAuth.getUser()возвращаетnull;- наборы ролей и разрешений пусты.
Аннотация @Auth или @Anonymous на методе имеет приоритет над аннотацией класса и позволяет переопределить общее правило контроллера.
Исключённые пути
spring:
smart:
mvc:
auth:
exclude-paths:
- /actuator/health
- /assets/**
Исключённые пути действуют в режимах GLOBAL и ANNOTATED. Они не попадают в перехватчик аутентификации SmartMVC, даже если найденный обработчик помечен @Auth.
Несколько ролей и разрешений
Стандартный AuthMode.ALL требует наличия каждого указанного значения:
@Auth(
roles = { "admin", "operator" },
permissions = { "user:read", "user:update" }
)
AuthMode.ANY требует хотя бы одного совпадения в каждой непустой группе:
@Auth(
roles = { "admin", "auditor" },
permissions = { "report:read", "report:export" },
mode = AuthMode.ANY
)
В этом примере требуется «хотя бы одна роль» и одновременно «хотя бы одно разрешение». Между группой ролей и группой разрешений всегда действует логическое AND.
Реализация аутентификации по умолчанию
Если приложение не предоставляет AuthInterceptor, Starter регистрирует PermitAllAuthInterceptor. Он создаёт данные пользователя с ролью-шаблоном * и разрешением *:*, благодаря чему пустой проект и демонстрационные примеры запускаются без дополнительной настройки.
В рабочем приложении с настоящей аутентификацией нужно обязательно предоставить собственную реализацию. В следующем разделе мы пошагово её создадим.