devpav
@devpav
Full-Stack разработчик.

Как связать user session с OAuth2Authorization и продливать user session при вызове с сервиса-клиента /oauth2/introspect?

Добрый день, дорогой друг.

Рассказываю интересную историю. Пишу свой SSO с spring security. Есть сервис-клиент, который получает авторизацию через SSO.

Действующие точки:

oauth2-client - c# приложение
server-oauth2 - SSO на spring security.

Что имею:

1. oauth2-client получает авторизацию через server-oauth2 и на server-oauth2 создается OAuth2Authorization, которая сохраняется в redis.

цепочка для деталий:

oauth2-client: GET localhost:8080/oauth2/authorize? client_id=************@oauth.client....
server-oauth2: GET localhost:5043/oauth2/charp?code=XQSuU0_hxT1nomJq5...
oauth2-client:POST localhost:8080/token?grant_type=authorization_code
server-oauth2: return tokens (access_token, refresh_token, exp)
oauth2-client:
POST http://localhost:8080/oauth2/introspect

Authorization: Basic ************************ # clientId:secretId in base64
Content-Type: application/json

{
    "token": "************************" # access token
}


server-oauth2: return token details + principal data

Соответственно, хожу рефрешить токен с oauth2-client каждые 30 минут.

2. пока пользователь пользуется oauth2-client, то с oauth2-client отправляется /oauth2/introspect на server-oauth2 (при каждом запросе) таким образом понимаю, что у пользователя OAuth2Authorization валидна и заодно обноляю пользовательские данные на oauth2-client (если необходимо).

3. Так как OAuth2Authorization содержит username нашего пользователя, то легко получить сессии пользователя через (RedisSessionRepository#findByUsername) а значит спокойно можно реализовать SLO. На oauth2-client вызывается logout - отправляем в server-oauth2 /oauth2/revoke. Что приводит к поиску сессий и их удаление. Все вроде хорошо, но нет.

Задача, которая мне пока не ясна:

Так как привязал все OAuth2Authorization к сессии и по окончанию сессии (timeout) сессия экспайрится, то пользовательская сессия умирает и с ней все OAuth2Authorization. Поведение как по мне вполне корректное, но для того чтобы сессия не умирала (пока ей пользуются внутри платформы), мне нужно обновлять lastAccessedTime при каждом вызове /oauth2/introspect. Таким образом буду говорить, что не убивай сессию, она еще активна.

Каким образом при вызове /oauth2/introspect из oauth2-client реализовать продление сессии пользователя?

@PS

Ипользую RedisIndexedSessionRepository. Соответственно пытаюсь обновить RedisSession#setLastAccessedTime таким образом, но в целом способ какой-то костыльный. Да и это не работает. Сессия продолжает экспайриться.

66fb338f6b4f8823178812.png

Redis

0.sorface.interview.session.0eb92b1f-6604-4fdc-aed2-c3105e880f8a - сессия oauth2-client
1.oauth2_auth_complete:54b15ec2-ffeb-403f-9297-9b9b3b5d8536 - OAuth2Authorization
1.sorface:session:index:org.springframework.session.FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME:developerdevpav - сессия принципала.
1.sorface.oauth2-complete - set с идентификаторами на 1.sorface.oauth2-complete:54b15ec2-ffeb-403f-9297-9b9b3b5d8536
1.sorface.oauth2-complete:54b15ec2-ffeb-403f-9297-9b9b3b5d8536 - здесь в качестве ключа выступает OAuth2Authorization#ID и проиндексированный principalName, accessToken, refreshToken. hash по сути связывает OAuth2Authorization - principal - session.
1.sorface:session:sessions:3bca540b-4d2c-45e6-8168-42a5f76aa949 - непосредственно данные сессии.

66fb36e89834c985079914.png

Подскажите в целом, правильный ли у меня подход к реализации таких историй? И может есть другой способ получения текущей сессии, кроме как через username, сохраненный в редис OAuth2Authorization?
  • Вопрос задан
  • 16 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы