带有oidc的Spring Security:刷新令牌

时间:2018-08-10 15:55:30

标签: spring-security jwt refresh-token oidc

具有Spring Security 5的Spring Boot 2可以配置为使用openID连接ID提供程序进行身份验证。 我设法通过配置Spring Security来设置我的项目-与各种经过完善的预先配置的安全机制(例如,减轻会话固定问题)配合使用都很好。

但是,似乎Spring Security过期时并不会自行刷新令牌(存储在会话中)。

是否有相应的设置?还是我必须自己进行刷新?

更新:Spring Boot 2.1已发布,因此现在该重新讨论此问题。我仍然不知道是否现在可以自动刷新accessToken或是否必须为此编写代码...

3 个答案:

答案 0 :(得分:3)

根据https://github.com/spring-projects/spring-security/issues/6742,似乎令牌没有被有意刷新:

ID令牌通常带有到期日期。 RP MAY 依靠它来终止RP会话。

春天没有。最后提到了两项增强功能,它们应该可以解决一些刷新问题-两者仍处于打开状态。

作为一种解决方法,我实现了一个 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)

在2.2.7.RELEASE版本中以spring-boot-starter-parent和依赖项实现:

  • spring-boot-starter-web
  • spring-boot-starter-security
  • spring-boot-starter-oauth2-client

由于我仍然不确定在Spring Boot中是否真的需要这样的开销,因此我很欣赏有关此变通办法的意见。

答案 1 :(得分:1)

根据文档

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

使用正确配置的WebClient时(如文档中所述),它将自动刷新。

  

Spring Security将自动刷新过期的令牌(如果存在刷新令牌)

支持刷新令牌的功能矩阵也支持此功能。

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

Spring Security 5上有一个较旧的博客,可让您访问可以手动执行的bean

rpm
  

在Spring应用程序上下文中将有一个OAuth2AuthorizedClientService自动配置为Bean,因此您只需将其注入到将要使用的任何位置即可。

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

OAuth2AuthenticationToken oauthToken =
    (OAuth2AuthenticationToken) authentication;

而且,现在无法找到它,但是我认为作为OAuth2AuthorizedClient client = clientService.loadAuthorizedClient( oauthToken.getAuthorizedClientRegistrationId(), oauthToken.getName()); String refreshToken = client.getRefreshToken(); 的一部分,有调用来进行刷新。

答案 2 :(得分:0)

即使悬赏100分,也无法给出答案。因此,我想目前没有实现使用Spring Security自动刷新访问令牌的机制。

有效的替代方法似乎是使用能够刷新令牌的spring boot keycloak适配器。