Spring Boot作为SP,如何获取OKTA(IDP)在POST请求中发送的RelayState值
获取Okta SAML SSO中的RelayState参数(Spring Boot实现)
在SP发起的SAML SSO流程中,Okta会通过HTTP POST请求将RelayState参数和SAML响应一起发送到你的ACS(断言消费者服务)地址。以下是两种在Spring Boot应用中获取该参数的实现方式:
方法1:直接从HttpServletRequest获取
RelayState是POST请求的表单参数之一,你可以在处理ACS请求的控制器方法中直接注入HttpServletRequest来获取:
import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationToken; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; @RestController public class SamlAcsController { // 路径需与Okta配置的ACS地址完全一致 @PostMapping("/saml/SSO") public String handleSamlResponse(HttpServletRequest request, @AuthenticationPrincipal Saml2AuthenticationToken authToken) { // 获取RelayState参数 String relayState = request.getParameter("RelayState"); // 处理SAML认证信息 String authenticatedUser = authToken.getName(); // 根据业务需求使用RelayState,比如跳转、参数传递等 if (relayState != null) { return String.format("用户 %s 认证成功,RelayState: %s", authenticatedUser, relayState); } return String.format("用户 %s 认证成功", authenticatedUser); } }
方法2:通过自定义AuthenticationSuccessHandler获取
如果需要在认证成功后统一处理跳转或业务逻辑,可以自定义AuthenticationSuccessHandler,在其中获取RelayState:
1. 实现自定义SuccessHandler
import org.springframework.security.core.Authentication; import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.net.URLDecoder; import java.nio.charset.StandardCharsets; public class CustomSamlSuccessHandler implements AuthenticationSuccessHandler { @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { // 获取并解码RelayState(如果参数被URL编码) String relayState = request.getParameter("RelayState"); if (relayState != null) { relayState = URLDecoder.decode(relayState, StandardCharsets.UTF_8); // 根据RelayState跳转至指定页面 response.sendRedirect(relayState); return; } // 默认跳转路径 response.sendRedirect("/dashboard"); } }
2. 在Spring Security配置中注册该Handler
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.web.SecurityFilterChain; @Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth .anyRequest().authenticated() ) .saml2Login(saml2 -> saml2 .successHandler(new CustomSamlSuccessHandler()) // 配置自定义成功处理器 ); return http.build(); } }
注意事项
- 确保Okta控制台中配置的ACS地址与你的控制器/路由路径完全匹配。
- RelayState参数可能会被URL编码,建议使用
URLDecoder解码后再使用。 - Okta默认允许传递RelayState参数,无需额外配置,若有特殊需求可在Okta的应用设置中调整。
内容的提问来源于stack exchange,提问作者SIMRAN KHOLIA
相关产品推荐
相关产品推荐

