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

基于Spring Boot 3.X与Java 17的SAML2认证升级咨询

Spring Security SAML扩展升级到SAML2:组件替换+可运行示例

一、核心组件替换对照表

旧SAML扩展组件新SAML2组件作用说明
SamlProcessingFilterSaml2WebSsoAuthenticationFilter处理IDP返回的SAML响应,完成认证逻辑
SamlAuthenticationProviderSaml2AuthenticationProvider验证SAML断言的合法性,转换为Spring Security认证对象
SamlEntryPointSaml2WebSsoAuthenticationRequestResolver生成并发起SAML认证请求到IDP,替代旧的入口跳转逻辑
MetadataManagerRelyingPartyRegistrationRepository管理SP(服务提供者)与IDP(身份提供者)的元数据配置,替代旧的元数据加载与管理逻辑
SamlLogoutFilterSaml2LogoutRequestFilter + Saml2LogoutResponseFilter处理SAML单点登出的请求与响应,拆分后的组件职责更单一

二、可运行完整配置示例

1. 依赖配置(Maven)

替换旧的spring-security-saml2-core依赖,引入官方SAML2服务提供者模块:

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-saml2-service-provider</artifactId>
    <version>6.2.x</version> <!-- 对应Spring Boot 3.2.x版本,按需调整 -->
</dependency>

2. 安全配置类

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.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticatedPrincipal;
import org.springframework.security.saml2.provider.service.authentication.Saml2Authentication;
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationProvider;
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration;
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
import org.springframework.security.saml2.provider.service.registration.InMemoryRelyingPartyRegistrationRepository;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class Saml2SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .anyRequest().authenticated()
            )
            // SAML2登录配置
            .saml2Login(saml2 -> saml2
                .authenticationManager(authenticationManager -> 
                    authenticationManager.authenticationProvider(saml2AuthenticationProvider())
                )
            )
            // SAML2登出配置
            .saml2Logout(saml2 -> saml2
                .logoutRequest(logoutRequest -> logoutRequest
                    .logoutUrl("/saml2/logout")
                )
            );
        return http.build();
    }

    // 配置SP与IDP的元数据关系
    @Bean
    public RelyingPartyRegistrationRepository relyingPartyRegistrationRepository() {
        RelyingPartyRegistration registration = RelyingPartyRegistration.withRegistrationId("my-sp")
            // IDP元数据地址(可替换为静态XML或本地文件路径)
            .idpEntityId("https://idp.example.com/saml2/idp/metadata")
            .idpMetadataLocation("https://idp.example.com/saml2/idp/metadata.xml")
            // SP实体ID(需与IDP配置中的SP实体ID一致)
            .entityId("https://my-sp.example.com/saml2/service-provider-metadata")
            // SP断言消费地址(默认是/saml2/authenticate/{registrationId})
            .assertionConsumerServiceLocation("https://my-sp.example.com/saml2/authenticate/my-sp")
            .build();
        return new InMemoryRelyingPartyRegistrationRepository(registration);
    }

    // 自定义SAML认证处理逻辑(可选,用于映射SAML断言到本地用户)
    @Bean
    public Saml2AuthenticationProvider saml2AuthenticationProvider() {
        Saml2AuthenticationProvider provider = new Saml2AuthenticationProvider();
        // 自定义用户信息转换:从SAML断言中提取属性映射到UserDetails
        provider.setAuthenticatedUserConverter(principal -> {
            String email = principal.getFirstAttribute("email");
            String username = principal.getFirstAttribute("username");
            // 这里可以对接本地用户系统,此处用内存用户示例
            UserDetails user = User.withUsername(username)
                .password("{noop}password") // 若无需本地密码可设为空,根据实际场景调整
                .roles("USER")
                .build();
            return new Saml2Authentication(user, principal, principal.getAuthorities());
        });
        return provider;
    }

    // 本地用户服务(可选,若需对接本地用户体系)
    @Bean
    public UserDetailsService userDetailsService() {
        UserDetails user = User.withUsername("user")
            .password("{noop}password")
            .roles("USER")
            .build();
        return new InMemoryUserDetailsManager(user);
    }
}

3. 元数据端点访问

Spring Security SAML2默认提供SP元数据端点:/saml2/service-provider-metadata/{registrationId},比如上述配置中可通过https://my-sp.example.com/saml2/service-provider-metadata/my-sp获取SP元数据,需提供给IDP配置使用。

三、关键注意事项

  • 版本兼容性:确保Spring Security版本与Spring Boot版本匹配(Spring Boot 3.x对应Spring Security 6.x)
  • IDP配置对齐:SP的实体ID、断言消费地址必须与IDP侧配置完全一致
  • 证书配置:若IDP使用自定义证书验证,需在RelyingPartyRegistration中配置验证证书(可通过signingX509Certificate方法)
  • 自定义逻辑扩展:如需处理断言加密、角色映射等复杂场景,可通过扩展Saml2AuthenticationProvider或自定义Saml2ResponseValidator实现

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 06:35:04