Spring Boot服务端无法获取Okta的Refresh Token求助
Spring Boot + Okta 登录后无法获取Refresh Token
我已经为运行在localhost:8080的Spring Boot应用配置Okta作为身份提供商,目前登录流程正常,但登录后只能获取到Access Token,Refresh Token始终为null。
相关信息
1. Okta应用配置

2. 日志打印结果
日志显示Access Token正常输出,但Refresh Token为null。
3. 后端代码
package com.okta.spring.example; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Configuration; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.oauth2.client.annotation.RegisteredOAuth2AuthorizedClient; import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; import org.springframework.security.oauth2.client.OAuth2AuthorizedClient; import org.springframework.security.oauth2.core.OAuth2AccessToken; import org.springframework.security.oauth2.core.OAuth2RefreshToken; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.servlet.ModelAndView; import java.util.Collections; @SpringBootApplication @EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true) public class CodeFlowExampleApplication { public static void main(String[] args) { SpringApplication.run(CodeFlowExampleApplication.class, args); } @Configuration static class WebConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/").permitAll() .anyRequest().authenticated() .and().logout().logoutSuccessUrl("/") .and().oauth2Client() .and().oauth2Login(); } } @Controller public class ExampleController { @GetMapping("/") public String home() { return "home"; } @GetMapping("/profile") @PreAuthorize("hasAuthority('SCOPE_profile')") public ModelAndView userDetails(OAuth2AuthenticationToken authentication, @RegisteredOAuth2AuthorizedClient OAuth2AuthorizedClient authorizedClient) { final OAuth2AccessToken accessToken = authorizedClient.getAccessToken(); System.out.println("AccessToken: {}" + accessToken.getTokenValue()); final OAuth2RefreshToken refreshToken = authorizedClient.getRefreshToken(); System.out.println("RefreshToken: {}" + refreshToken); System.out.println(authentication.getCredentials()); return new ModelAndView("userProfile" , Collections.singletonMap("details", authentication.getPrincipal().getAttributes())); } } }
4. 登录跳转表单代码
<form method="get" th:action="@{/oauth2/authorization/okta}" th:unless="${#authorization.expression('isAuthenticated()')}"> <button id="login-button" class="btn btn-primary" type="submit">Login</button> </form>
解决方案
要获取Refresh Token,需确保以下配置正确:
1. Okta应用端配置
- 确认Okta应用类型为Web应用,在控制台的应用配置中,授权类型必须勾选
Authorization Code和Refresh Token。 - 检查登录重定向URI是否设置为
http://localhost:8080/login/oauth2/code/okta,与Spring Boot配置保持一致。 - 在
Refresh Token设置中,避免将刷新令牌行为设为一次性(除非业务特殊需求),同时确认令牌有效期配置合理。
2. Spring Boot配置调整
- 在
application.properties或application.yml中,显式配置OAuth2客户端的scope包含offline_access(这是获取Refresh Token的必要权限):
spring.security.oauth2.client.registration.okta.scope=openid,profile,email,offline_access
- 确认授权类型为
authorization_code(默认值,显式配置更稳妥):
spring.security.oauth2.client.registration.okta.authorization-grant-type=authorization_code
3. 代码与日志排查
- 当前代码中
oauth2Login()和oauth2Client()配置无问题,无需修改登录表单,Spring Boot会自动携带配置的scope发起授权请求。 - 若仍无法获取,开启调试日志查看授权请求细节:
logging.level.org.springframework.security.oauth2=DEBUG logging.level.org.springframework.security=DEBUG
通过日志可确认请求是否包含offline_access,以及Okta响应中是否返回Refresh Token。
内容的提问来源于stack exchange,提问作者Nitinram Velraaj
相关产品推荐
相关产品推荐

