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

Spring Boot 3.4.1升级后SAML证书无法识别为PemContent问题

Spring Boot 3.4.1 SAML认证非PEM格式证书无法识别的解决方案

问题背景

从Spring Boot 3.3.6升级到3.4.1后,原SAML认证配置中的非PEM格式.cer证书无法被识别,抛出IllegalStateException: Missing certificates or unrecognized format异常。核心原因是Saml2RelyingPartyRegistrationConfiguration#readCertificate方法实现变更:

  • 3.3.x版本通过CertificateFactory.getInstance("X.509")直接读取多种X.509证书格式(包括DER编码的.cer)
  • 3.4.x版本改为仅支持PEM格式的PemContent解析,导致非PEM证书无法加载

原配置示例:

spring.security.saml2:
  relyingparty:
    registration:
      azuread:
        entity-id: ArchitecturePoC
        assertingparty:
          verification:
            credentials:
              - certificate-location: "classpath:ArchitecturePoC.cer"

解决方案

方案1:将证书转换为PEM格式

这是最直接的解决方式,使用openssl工具将DER编码的.cer转换为PEM格式:

openssl x509 -inform der -in ArchitecturePoC.cer -out ArchitecturePoC.pem

修改配置文件中的证书路径:

spring.security.saml2:
  relyingparty:
    registration:
      azuread:
        entity-id: ArchitecturePoC
        assertingparty:
          verification:
            credentials:
              - certificate-location: "classpath:ArchitecturePoC.pem"

方案2:自定义证书读取逻辑(覆盖自动配置)

如果需要保留原有.cer证书格式,可以自定义RelyingPartyRegistrationRepository,沿用3.3.x版本的证书读取逻辑:

@Configuration
public class CustomSaml2RelyingPartyConfig {

    @Bean
    public RelyingPartyRegistrationRepository relyingPartyRegistrationRepository() {
        RelyingPartyRegistration registration = RelyingPartyRegistration.withRegistrationId("azuread")
                .entityId("ArchitecturePoC")
                .assertingParty(assertingParty -> assertingParty
                        .verification(verification -> verification
                                .credentials(credentials -> credentials
                                        .add(credential -> credential.x509Certificate(readCertificate(new ClassPathResource("ArchitecturePoC.cer"))))
                                )
                        )
                )
                .build();
        return new InMemoryRelyingPartyRegistrationRepository(registration);
    }

    private X509Certificate readCertificate(Resource location) {
        Assert.state(location != null, "No certificate location specified");
        Assert.state(location.exists(), () -> "Certificate location '" + location + "' does not exist");
        try (InputStream inputStream = location.getInputStream()) {
            return (X509Certificate) CertificateFactory.getInstance("X.509").generateCertificate(inputStream);
        } catch (Exception ex) {
            throw new IllegalArgumentException("Failed to load certificate from " + location, ex);
        }
    }
}

方案3:使用自定义器修改现有注册项

如果不想完全替换自动配置,可通过Saml2RelyingPartyRegistrationCustomizer针对特定注册项替换证书加载逻辑:

@Configuration
public class Saml2CertificateCustomizer {

    @Bean
    public Saml2RelyingPartyRegistrationCustomizer certificateLoadingCustomizer() {
        return (registrationId, builder) -> {
            if ("azuread".equals(registrationId)) {
                X509Certificate cert = readCertificate(new ClassPathResource("ArchitecturePoC.cer"));
                builder.assertingParty(party -> party
                        .verification(verification -> verification
                                .credentials(creds -> creds.clear().add(c -> c.x509Certificate(cert)))
                        )
                );
            }
        };
    }

    private X509Certificate readCertificate(Resource location) {
        Assert.state(location != null, "No certificate location specified");
        Assert.state(location.exists(), () -> "Certificate location '" + location + "' does not exist");
        try (InputStream inputStream = location.getInputStream()) {
            return (X509Certificate) CertificateFactory.getInstance("X.509").generateCertificate(inputStream);
        } catch (Exception ex) {
            throw new IllegalArgumentException("Failed to load certificate from " + location, ex);
        }
    }
}

方案对比

  • 方案1:操作简单,无需代码修改,适合快速解决问题
  • 方案2/3:保留原有证书格式,适合无法修改证书文件的场景,代码侵入性低

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 22:53:15