如何在Spring Boot Security OAuth2流程设置access_type=offline获取refresh_token
解决方案
1 修正参数配置错误
你当前将access_type: offline配置在providerConfigurationMetadata中属于无效配置,该属性仅用于存储OpenID服务提供者的元数据,不会被携带到授权请求的查询参数中,谷歌服务无法识别到你需要离线访问权限,因此不会返回refresh_token。
你需要自定义OAuth2AuthorizationRequestResolver,将自定义参数注入到授权请求中,参考配置如下:
// 注册自定义授权请求解析器 @Bean public OAuth2AuthorizationRequestResolver googleOAuth2AuthorizationRequestResolver(ClientRegistrationRepository clientRegistrationRepository) { DefaultOAuth2AuthorizationRequestResolver defaultResolver = new DefaultOAuth2AuthorizationRequestResolver( clientRegistrationRepository, OAuth2AuthorizationRequestRedirectFilter.DEFAULT_AUTHORIZATION_REQUEST_BASE_URI ); defaultResolver.setAuthorizationRequestCustomizer(customizer -> { // 仅对谷歌客户端添加专属参数 if ("g_mail".equals(customizer.getClientRegistration().getRegistrationId())) { customizer.additionalParameters(params -> { params.put("access_type", "offline"); // 可选配置:强制弹出授权确认页,确保每次授权都返回refresh_token params.put("prompt", "consent"); }); } }); return defaultResolver; }
之后将解析器配置到安全过滤链中:
@Bean public SecurityFilterChain securityFilterChain(HttpSecurity http, OAuth2AuthorizationRequestResolver authRequestResolver) throws Exception { http // 其余安全配置保持不变 .oauth2Login(oauth2Config -> oauth2Config .authorizationEndpoint(endpointConfig -> endpointConfig .authorizationRequestResolver(authRequestResolver) ) // 原有回调处理逻辑保持不变 ); return http.build(); }
配置完成后可以删除你原有代码中的providerConfigurationMetadata(configMap)相关配置。
2 谷歌服务返回refresh_token的注意事项
- 谷歌默认仅在用户首次授权你的应用时返回refresh_token,如果用户之前已经完成过授权,没有重新同意授权的情况下不会重复返回refresh_token,添加
prompt=consent参数可以强制用户重新确认授权,每次授权都会返回新的refresh_token。 - 如果你在谷歌云控制台创建的OAuth应用处于测试状态,下发的refresh_token有效期仅为7天,需要将应用发布为正式状态才能获取长期有效的refresh_token。
- 拿到refresh_token后需要自行持久化存储,后续access_token过期时可直接用refresh_token换取新的access_token,无需用户再次授权。
3 快速排查验证
配置完成后可以打印跳转至谷歌的授权请求链接,确认链接中已携带access_type=offline参数,即可确认配置生效。
内容的提问来源于stack exchange,提问作者Manish Chandra Ranga
相关产品推荐
相关产品推荐

