spring security 5.7+ 不再原生支持 saml,移除了 spring-security-saml2-core 模块,必须改用 spring-security-saml2-service-provider;需手动配置元数据 endpoint、证书校验、自定义属性映射。

Spring Security 5.7+ 不再原生支持 SAML
直接说结论:Spring Security 5.7 起移除了 spring-security-saml2-core 模块,官方不再维护 SAML 2.0 支持。如果你用的是 Spring Boot 3.x(对应 Spring Security 6.x),WebSecurityConfigurerAdapter 已废弃,旧的 SAML 配置方式完全失效。
这意味着——不是配置不对,而是“根本没这个类了”。常见错误现象包括:ClassNotFoundException: org.springframework.security.saml.SAMLAuthenticationFilter、IDE 找不到 SAMLBootstrap、Maven 编译报 spring-security-saml2-core 无法解析。
- 必须改用 Spring Security 官方推荐的替代方案:
spring-security-saml2-service-provider(仅 SP 端,即你的 Java 应用作为服务提供方) - 该模块只支持 SAML 2.0 Web SSO,不支持 IDP 功能(不能当身份源)
- 最低要求 Spring Security 5.7.0+,Spring Boot 2.7+ 或 3.x(但 3.x 需额外适配 Jakarta EE 9+ 命名空间)
- 旧项目升级时,所有
SAMLContextProvider、SAMLProcessingFilter类全部作废,不能复用
如何注册 SAML 服务提供方(SP)元数据
SAML 流程里,你的应用得先告诉 IDP “我是谁、我能接收什么断言、签名密钥长啥样”——这靠元数据(metadata)交换。Spring Security SAML2 不自动生成 XML 元数据文件,得手动构造或靠 endpoint 输出。
关键点是启用 /saml2/service-provider-metadata/{registrationId} 这个内置 endpoint,它会动态生成符合 SAML 2.0 标准的 SP 元数据 XML。
- 确保在
application.yml中至少定义一个 registrationId,例如:spring.security.saml2.relyingparty.registration.my-sp - 启动后访问
http://localhost:8080/saml2/service-provider-metadata/my-sp即可拿到 XML - 该 endpoint 默认 require 认证,如需未登录也能访问,需在安全配置中放行:
requestMatchers("/saml2/service-provider-metadata/**").permitAll() - IDP 配置时,务必上传此 XML(而非手写),否则常见错误:
Invalid issuer in assertion或Signature validation failed
验证 SAML 响应签名和证书的坑
SAML 断言默认带 XML 签名,Spring Security SAML2 要求你显式提供 IDP 的公钥证书(X.509 PEM 格式),否则会抛 org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationException: Failed to validate signature。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
这不是可选步骤,是强制校验环节。容易被忽略的是证书格式和加载方式。
- 证书必须是 PEM 格式(以
-----BEGIN CERTIFICATE-----开头),不能是 DER 或 JKS - 路径要写对:
spring.security.saml2.relyingparty.registration.my-sp.identityprovider.certificate-location=classpath:idp.crt - 如果证书链含中间 CA,必须合并进同一文件(顺序:leaf → intermediate → root)
- 调试时可在日志加
logging.level.org.springframework.security.saml2=DEBUG,看是否成功加载证书及签名算法(如SHA-256withRSA) - 部分 IDP 默认用
SHA-1签名,而 Spring Security SAML2 6.x 默认禁用 SHA-1,需显式开启:.signatureAlgorithms("http://www.w3.org/2000/09/xmldsig#rsa-sha1")
自定义 SAML 用户属性映射到 UserDetails
默认情况下,Spring Security SAML2 只把 Subject.NameID 当用户名,其余属性(如邮箱、角色)全丢弃。业务系统几乎都需要从 AttributeStatement 里提取字段,比如 mail、groups。
靠 RelyingPartyRegistration 的 assertionConsumerService 无法做到,必须注册自定义 Saml2AuthenticationConverter。
- 实现
Converter<saml2authenticationtoken saml2authenticatedprincipal></saml2authenticationtoken>,重写convert()方法 - 从
token.getSaml2Response().getAssertions().get(0).getAttributeStatements()里遍历提取属性 - 注意:SAML 属性名大小写敏感,且可能带命名空间前缀(如
urn:oid:0.9.2342.19200300.100.1.3对应 email),别硬写字符串匹配 - 角色映射建议用
SimpleGrantedAuthority包装,并确保前缀为ROLE_,否则@PreAuthorize("hasRole('ADMIN')")不生效 - 别在 converter 里做远程调用(如查 DB),否则影响登录性能;属性缺失时返回空集合,别 throw 异常
复杂点在于 SAML 属性结构不统一——不同 IDP 返回的字段名、嵌套层级、编码方式(Base64?URI?)都可能不同。上线前一定拿真实 IDP 的响应 XML 做解析验证,而不是只测 mock 数据。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










