反向代理下Spring Security 6 SAML2 SP认证异常排查求助
问题:反向代理下Spring Security 6 SAML2 SP解密失败,提示无依赖方注册
我用OpenSAML结合Spring Security 6搭建SAML2服务提供商(SP),本地运行完全正常,但部署到反向代理后,SAML响应无法正确处理,抛出如下异常:
mes:tc:SAML:2.0:assertion}EncryptedAssertion │ with propagation set to true │ │2024-10-27 11:46:04.302000[http-nio-5003-exec-175] TRACE o.o.core.xml.AbstractXMLObject - Releasing cached DOM reprsentation for {urn:oasis:names:tc:SAML:2.0:protocol}Response ┤ │2024-10-27 11:46:04.302000[http-nio-5003-exec-175] TRACE o.o.core.xml.AbstractXMLObject - Releasing cached DOM reprsentation for parent of {urn:oasis:names:tc:SAML:2.0:protocol}Response with propag│ ation set to true ┤ │2024-10-27 11:46:04.302000[http-nio-5003-exec-175] TRACE o.s.s.s.p.s.w.a.Saml2WebSsoAuthenticationFilter - Failed to process authentication request ┤ │org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationException: No relying party registration found ┤ │ at org.springframework.security.saml2.provider.service.web.authentication.Saml2WebSsoAuthenticationFilter.attemptAuthentication(Saml2WebSsoAuthenticationFilter.java:127) ┤ │ at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:231) ┤ │ at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:221) ┤ │ at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ┤ │ at org.springframework.security.saml2.provider.service.web.Saml2WebSsoAuthenticationRequestFilter.doFilterInternal(Saml2WebSsoAuthenticationRequestFilter.java:100) ┤ │ at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ┤ │ at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ┤ │ at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:107) ┤ │ at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:93) ┤ │ at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ┤ │ at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90) │ │ at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75) │ │ at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ┤ │ at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) │ │ at org.springframework.security.web.context.SecurityContextHolderFilter.doFilter(SecurityContextHolderFilter.java:82) ┤ │ at org.springframework.security.web.context.SecurityContextHolderFilter.doFilter(SecurityContextHolderFilter.java:69) ┤ │ at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) │ │ at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:62) ┤ │ at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
流量路径为:https://my.public.domain/ → http://internal/(SAML2 SP部署在internal节点)。请问:
- 是否需要在SP中处理
X-Forwarded-Proto这类HTTPS相关头信息? - 反向代理的证书是否会干扰通信?
SP已配置本地自签名证书用于签名和解密,核心代码如下:
RSAPrivateKey k = RsaKeyConverters.pkcs8().convert(new FileInputStream(privateKeyResource)); log.info("certificate path:"+certificateResource.getAbsolutePath()); log.info("private key path:"+privateKeyResource.getAbsolutePath()); X509Certificate certificate = X509Support.decodeCertificate(certificateResource); Saml2X509Credential credential = Saml2X509Credential.signing(k, certificate); Saml2X509Credential decryptCredential = Saml2X509Credential.decryption(k, certificate); RelyingPartyRegistration registration = RelyingPartyRegistrations .fromMetadataLocation("classpath:saml/metadata.xml").registrationId(relyingPartyEntityId) .authnRequestsSigned(true) .signingX509Credentials(c -> c.add(credential)) .decryptionX509Credentials(c -> c.add(decryptCredential)) .assertingPartyDetails(party -> party .entityId(relyingPartyEntityId) ).assertionConsumerServiceLocation(virtuACSLocation) .entityId(relyingPartyEntityId) .build();
解答
1. 必须处理X-Forwarded-Proto这类转发头
异常核心是No relying party registration found,并非直接的解密失败——Spring Security在处理SAML响应时,会校验请求的ACS(断言消费者服务)地址与依赖方注册中配置的地址是否一致。
反向代理后,SP内部收到的请求协议是HTTP,但IDP那边配置的ACS地址是HTTPS的公网地址(https://my.public.domain/...),协议不匹配会导致Spring无法找到对应的依赖方注册,进而抛出异常。
解决方法:
- 在Spring Boot配置文件中添加:
让服务器自动识别反向代理传递的server.forward-headers-strategy=NATIVEX-Forwarded-Proto、X-Forwarded-Host等头,还原真实的请求地址。 - 或者在SecurityFilterChain中显式配置
ForwardedHeaderFilter,确保Spring能正确解析真实请求信息。
2. 反向代理证书不会干扰SAML通信
SAML的加密、签名操作是SP与IDP之间的端到端流程,使用的是你配置的自签名SAML证书。反向代理的证书仅用于客户端(用户浏览器)与反向代理之间的HTTPS通信,和SP与IDP的SAML加密逻辑完全无关。
但需要确保反向代理不篡改SAML响应的内容和请求头,否则会导致签名验证失败或XML解析错误。
额外排查点
- 确认IDP元数据中配置的ACS地址,与你代码中
virtuACSLocation的值完全一致(必须是https://my.public.domain/...)。 - 检查反向代理是否正确传递了
X-Forwarded-Proto: https、X-Forwarded-Host: my.public.domain头。 - 开启Spring Security的DEBUG日志,查看依赖方匹配时的URL对比细节,确认地址/协议不匹配的具体原因。
内容的提问来源于stack exchange,提问作者knocker_d
相关产品推荐
相关产品推荐

