Spring Boot集成spring-boot-starter-oauth2-client后token过期如何用refresh token刷新
Spring Boot OAuth2 Client refresh token刷新实现方案
结论
完全可以使用refresh token实现token无感刷新,Spring Security OAuth2 Client组件原生提供了该能力,不需要自行实现刷新逻辑。
前置要求
你对接的身份提供商(IDP)支持refresh token发放,且必须在客户端配置的scope中添加offline_access,绝大多数IDP只有收到该scope才会在登录成功后返回refresh token。
具体实现步骤
1. 调整OAuth2客户端配置
在application.yml或application.properties中添加对应配置,yml示例如下:
spring: security: oauth2: client: provider: # 替换为你自定义的IDP标识 custom-idp: issuer-uri: 你的IDP服务签发地址 registration: custom-idp: client-id: 你的客户端ID client-secret: 你的客户端密钥 # 必须添加offline_access scope: openid,profile,offline_access authorization-grant-type: authorization_code redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"
2. 注入支持refresh token的OAuth2AuthorizedClientManager
Spring Security默认的客户端管理器没有启用refresh token能力,需要手动配置注入:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.oauth2.client.*; import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; import org.springframework.security.web.SecurityFilterChain; @Configuration @EnableWebSecurity public class OAuth2SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http, OAuth2AuthorizedClientManager authorizedClientManager) throws Exception { http .authorizeHttpRequests(auth -> auth // 你的权限规则 .anyRequest().authenticated() ) .oauth2Login(oauth2 -> oauth2 .authorizedClientManager(authorizedClientManager) ) // 如果你同时作为客户端调用其他OAuth2资源,需要添加下方配置 .oauth2Client(oauth2 -> oauth2 .authorizedClientManager(authorizedClientManager) ); return http.build(); } @Bean public OAuth2AuthorizedClientManager authorizedClientManager( ClientRegistrationRepository clientRegistrationRepository, OAuth2AuthorizedClientService authorizedClientService) { // 构建支持多种授权模式的provider,加入refreshToken能力 OAuth2AuthorizedClientProvider clientProvider = OAuth2AuthorizedClientProviderBuilder.builder() .authorizationCode() .refreshToken() .clientCredentials() .build(); DefaultOAuth2AuthorizedClientManager clientManager = new DefaultOAuth2AuthorizedClientManager( clientRegistrationRepository, authorizedClientService ); clientManager.setAuthorizedClientProvider(clientProvider); return clientManager; } // 如果要使用@Secured注解,需要额外开启方法级安全 @EnableMethodSecurity(securedEnabled = true) public static class MethodSecurityConfig { } }
3. (可选)配置refresh token过期后的跳转逻辑
如果refresh token本身也过期,刷新会失败,默认会返回401异常,你可以配置自动跳转到IDP登录页:
在上面的SecurityFilterChain配置中添加异常处理规则:
http.exceptionHandling(ex -> ex .authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/oauth2/authorization/custom-idp")) );
效果验证
配置完成后,当access token过期时,Spring Security会自动用本地存储的refresh token向IDP发起刷新请求,获取新的token信息后替换旧的存储值,整个过程用户无感知,不会触发登录跳转。只有当refresh token也过期失效时,才会跳转回IDP登录页面。
内容的提问来源于stack exchange,提问作者Detlef Brendle
相关产品推荐
相关产品推荐

