Как генерируются права доступа и как сервис получает список прав пользователя
Что проверяют
Понимаете ли вы весь путь: где права описаны, кто выдаёт их пользователю и как сервис узнаёт о них при запросе. Следом обычно спрашивают, что будет, если роль у пользователя отобрали, а токен ещё жив.
Как отвечать
Разбейте ответ на три части.
Модель. Классика это RBAC: таблицы users, roles, permissions и связующие user_roles и role_permissions, обе многие ко многим. Права вида orders:write заводят разработчики в коде и миграциях Flyway или Liquibase, роли собирает и назначает администратор. Если решение зависит от атрибутов (свой отдел, сумма заказа), это уже ABAC с правилами в политиках.
Получение. Два основных варианта:
- права в токене: сервер авторизации (Keycloak, Spring Authorization Server) кладёт роли или scope в JWT. Сервис как Resource Server проверяет подпись по JWKS и превращает клеймы в
GrantedAuthorityчерезJwtAuthenticationConverter, без походов в базу; - права по запросу: в токене только идентификатор, сервис берёт права у сервиса доступа или через
UserDetailsServiceи кеширует их в Caffeine или Redis с TTL и сбросом по событию смены ролей.
Проверка. В Spring Security 6 это @EnableMethodSecurity и @PreAuthorize("hasAuthority('orders:write')") на методах или правила в SecurityFilterChain. Помните, что hasRole('ADMIN') ищет authority с префиксом, то есть ROLE_ADMIN.
Где спотыкаются
Кладут в JWT все права пользователя. Токен раздувается до лимита на размер заголовков, а отозванное право работает до истечения токена. Помогают короткоживущий access-токен и обновление через refresh.
Связывают право с ролью колонкой role_id в permissions. Тогда одно право принадлежит одной роли, а нужна связующая таблица.
Проверяют доступ только на шлюзе или во фронтенде. Каждый сервис обязан проверять права сам, иначе прямой вызов в обход шлюза пройдёт без авторизации.