Spring Security с oidc: обновите токены

Spring Boot 2 с Spring Security 5 можно настроить для использования поставщика идентификатора подключения openID для аутентификации. Мне удалось настроить свой проект, просто настроив Spring Security - он отлично работает со всеми видами идеально настроенных механизмов безопасности, таких как уменьшение фиксации сеанса.

Но кажется, что Spring Security не обновляет токены (которые хранятся в сеансе) самостоятельно, когда срок их действия истек.

Есть ли для этого настройки или мне нужно самому заботиться об обновлении?

Обновлять: Выпущена Spring Boot 2.1, так что пришло время вернуться к этой проблеме. Я до сих пор не знаю, можно ли теперь автоматически обновлять accessToken или мне нужно написать для этого код ...

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
12
0
4 300
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

даже награда в 100 очков репутации не дала ответа. Поэтому я предполагаю, что в настоящее время не реализован механизм для автоматического обновления токена доступа с помощью Spring Security.

Действительной альтернативой, похоже, является адаптер Spring boot keycloak, который может обновлять токен.

В последней документации docs.spring.io/spring-security/site/docs/current/reference/… говорится, что при получении токена обновления Spring Security должна автоматически пытаться обновить его. github.com/spring-projects/spring-security/wiki/… также поддерживает, что он поддерживается

Darren Forsythe 07.11.2018 16:31

@DarrenForsythe спасибо за ссылки - как насчет того, чтобы удовлетворить это как ответ, чтобы я мог назначить вам награду?

rdmueller 07.11.2018 19:30

поэтому кажется, что веб-клиент обрабатывает токен обновления. Итак, насколько я понимаю, приложение получает запрос на конечную точку, и только если контроллер пытается использовать токен доступа через webClient, токен обновления будет использоваться. Интересная концепция ... Адаптер Keycloak уже обновляет accesstoken входящим запросом ...

rdmueller 07.11.2018 19:34

Я не уверен в базовой реализации поддержки получения и обновления токенов и т. д. С помощью веб-клиента, с которым я в настоящее время сталкиваюсь с проблемой сам, но из того, что я видел в коде, если вы аутентифицировали, он попробует для обновления, если токен обновления доступен для объекта аутентификации по запросу для данного поставщика. Также возможно получить bean-компоненты более низкого уровня и сделать это самостоятельно, spring.io/blog/2018/03/06/… имеет пример этого

Darren Forsythe 07.11.2018 19:39

любая идея, если как это сделать с новым весенним выпуском безопасности ??? Можем ли мы использовать любой настраиваемый фильтр для обновления токена и обновления участника?

Agam 01.12.2019 23:30

@agam: старайтесь избегать пользовательских фильтров. с настройками должно быть все возможно, но иногда они скрыты. Я получил лучшие результаты с адаптерами keycloak вместо пружинной защиты.

rdmueller 02.12.2019 08:24

Спасибо. Я взгляну на адаптер keycloak. Тем временем я смог сделать это с помощью настраиваемого фильтра. Как вы сказали, мне следует избегать этого, по какой-то конкретной причине ??

Agam 02.12.2019 17:29

Я добавил сюда свое решение. хочешь посмотреть? stackoverflow.com/questions/59144160/…

Agam 02.12.2019 18:47

Согласно документации,

https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#webclient

При использовании правильно настроенного WebClient, как указано в документации, он будет автоматически обновлен.

Spring Security will automatically refresh expired tokens (if a refresh token is present)

Это также поддерживается матрицей функций, в которой поддерживаются токены обновления.

https://github.com/spring-projects/spring-security/wiki/OAuth-2.0-Features-Matrix

Был более старый блог о Spring Security 5, который дает вам доступ к bean-компонентам, которые вы можете сделать вручную,

Authentication authentication =
    SecurityContextHolder
        .getContext()
        .getAuthentication();

OAuth2AuthenticationToken oauthToken =
    (OAuth2AuthenticationToken) authentication;

There will be an OAuth2AuthorizedClientService automatically configured as a bean in the Spring application context, so you’ll only need to inject it into wherever you’ll use it.

OAuth2AuthorizedClient client =
    clientService.loadAuthorizedClient(
            oauthToken.getAuthorizedClientRegistrationId(),
            oauthToken.getName());

String refreshToken = client.getRefreshToken();

И, не могу найти его прямо сейчас, но я предполагаю, что как часть OAuth2AuthorizedClientExchangeFilterFunction есть вызовы для обновления.

Спасибо за подробный ответ!

rdmueller 08.11.2018 06:07
Ответ принят как подходящий

Согласно https://github.com/spring-projects/spring-security/issues/6742 кажется, что токен намеренно не обновляется:

An ID Token typically comes with an expiration date. The RP MAY rely on it to expire the RP session.

Spring - нет. В конце упоминаются два улучшения, которые должны решить некоторые проблемы с обновлением - оба все еще открыты.

В качестве обходного пути я реализовал GenericFilterBean, который проверяет токен и очищает аутентификацию в текущем контексте безопасности. Таким образом, необходим новый токен.

@Configuration
public class RefreshTokenFilterConfig {

    @Bean
    GenericFilterBean refreshTokenFilter(OAuth2AuthorizedClientService clientService) {
        return new GenericFilterBean() {
            @Override
            public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
                Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
                if (authentication != null && authentication instanceof OAuth2AuthenticationToken) {
                    OAuth2AuthenticationToken token = (OAuth2AuthenticationToken) authentication;
                    OAuth2AuthorizedClient client =
                            clientService.loadAuthorizedClient(
                                    token.getAuthorizedClientRegistrationId(),
                                    token.getName());
                    OAuth2AccessToken accessToken = client.getAccessToken();
                    if (accessToken.getExpiresAt().isBefore(Instant.now())) {
                        SecurityContextHolder.getContext().setAuthentication(null);
                    }
                }
                filterChain.doFilter(servletRequest, servletResponse);
            }
        };
    }
}

Кроме того, мне пришлось добавить фильтр в конфигурацию безопасности:

@Bean
public WebSecurityConfigurerAdapter webSecurityConfigurer(GenericFilterBean refreshTokenFilter) {
    return new WebSecurityConfigurerAdapter() {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                   .addFilterBefore(refreshTokenFilter,  AnonymousAuthenticationFilter.class)

Реализовано с помощью spring-boot-starter-parent и зависимостей в версии 2.2.7.RELEASE:

  • Spring-Boot-Starter-Web
  • весна-загрузки-стартер-безопасность
  • весна-загрузка-стартер-oauth2-клиент

Я ценю мнения об этом обходном пути, так как я все еще не уверен, действительно ли нужны такие накладные расходы в Spring Boot.

Для тех, кто все еще ищет решение, это docs.spring.io/spring-security/site/docs/5.1.2.RELEASE/…. WebClient - это лекарство.

ejazazeem 11.03.2021 11:04

Другие вопросы по теме