You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在新版Spring Security中添加SAML RelayState

Spring Security SAML2(5.6.0-RC1)SP发起SSO添加RelayState实现

在旧版OpenSAML及openSAML-extensions库中,为SP发起的SSO添加RelayState很简单——重写SAMLEntryPoint类的WebSSOProfileOptions,再在MessageContext上设置RelayState即可。但升级到对应Spring Security 5.6.0-RC1文档的新版库后,很多开发者找不到实现路径,试过多种方案都没解决。目前不少人用samesite=none Cookie匹配请求响应,但RelayState的实现更优雅、容错性更强,以下是具体实现步骤:

实现步骤

1. 自定义Saml2AuthenticationRequestResolver

创建自定义解析器,在生成认证请求时注入RelayState值:

import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationRequestContext;
import org.springframework.security.saml2.provider.service.web.authentication.Saml2AuthenticationRequestResolver;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Optional;

public class CustomSaml2AuthenticationRequestResolver implements Saml2AuthenticationRequestResolver {

    private final Saml2AuthenticationRequestResolver delegate;

    public CustomSaml2AuthenticationRequestResolver(Saml2AuthenticationRequestResolver delegate) {
        this.delegate = delegate;
    }

    @Override
    public Optional<Saml2AuthenticationRequestContext> resolve(HttpServletRequest request, HttpServletResponse response) {
        Optional<Saml2AuthenticationRequestContext> context = this.delegate.resolve(request, response);
        return context.map(ctx -> {
            // 从请求参数、会话或其他地方获取RelayState,这里示例从请求参数取
            String relayState = request.getParameter("relayState");
            return Saml2AuthenticationRequestContext.with(ctx)
                    .relayState(relayState)
                    .build();
        });
    }
}

2. 配置SecurityFilterChain替换默认解析器

在Spring Security配置类中,将自定义解析器注入,替换默认实现:

import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.saml2.provider.service.web.authentication.OpenSaml4AuthenticationRequestResolver;
import org.springframework.security.web.SecurityFilterChain;

@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
                .authorizeHttpRequests(auth -> auth
                        .anyRequest().authenticated()
                )
                .saml2Login(saml2 -> saml2
                        .authenticationRequestResolver(resolver -> {
                            OpenSaml4AuthenticationRequestResolver defaultResolver = 
                                    new OpenSaml4AuthenticationRequestResolver(resolver.getRelyingPartyRegistrationRepository());
                            resolver.setAuthenticationRequestResolver(
                                    new CustomSaml2AuthenticationRequestResolver(defaultResolver)
                            );
                        })
                );
        return http.build();
    }
}

3. 登录成功后获取并使用RelayState

IdP重定向回SP时,Spring Security会自动携带RelayState,你可以通过Saml2AuthenticationToken直接获取:

import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationToken;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class AuthController {

    @GetMapping("/login/saml2/success")
    public String loginSuccess(Saml2AuthenticationToken token) {
        String relayState = token.getRelayState();
        // 根据业务需求处理RelayState,比如跳转指定页面
        return "登录成功,RelayState: " + relayState;
    }
}

内容的提问来源于stack exchange,提问作者Taliebram

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 11:39:25