SAML Java Spring Boot - 不可信凭证的 PKIX 路径构建失败
SAML Java Sping Boot - PKIX path construction failed for untrusted credential
运行 在 Java 中设置 SAML 2.0 的这个问题 Spring 使用最新的库启动。
这里有一些相关代码,但如果还有其他帮助,请告诉我:
@Bean
public KeyManager keyManager()
{
return new JKSKeyManager(keyStoreResource, keystorePassword, ImmutableMap.of(keystoreKeyAlias, keystorePrivateKeyPassword), keystoreKeyAlias);
}
@Bean
public SAMLDiscovery samlIDPDiscovery()
{
return new SAMLDiscovery();
}
@Bean
public MetadataDisplayFilter metadataDisplayFilter()
{
return new MetadataDisplayFilter();
}
@Bean
public TLSProtocolConfigurer tlsProtocolConfigurer()
{
TLSProtocolConfigurer t = new TLSProtocolConfigurer();
//t.setSslHostnameVerification("allowAll");
return t;
}
// Configure TLSProtocolConfigurer
@Bean
public ProtocolSocketFactory protocolSocketFactory()
{
//return new TLSProtocolSocketFactory(keyManager(), null, "defaultAndLocalhost");
return new TLSProtocolSocketFactory(keyManager(), null, "default");
}
@Bean
public Protocol protocol()
{
return new Protocol("https", protocolSocketFactory(), 443);
}
@Bean
public MethodInvokingFactoryBean socketFactoryInitialization()
{
MethodInvokingFactoryBean methodInvokingFactoryBean = new MethodInvokingFactoryBean();
methodInvokingFactoryBean.setTargetClass(Protocol.class);
methodInvokingFactoryBean.setTargetMethod("registerProtocol");
methodInvokingFactoryBean.setArguments(new Object[] { "https", protocol() });
return methodInvokingFactoryBean;
}
@Bean
public CachingMetadataManager metadata() throws MetadataProviderException
{
HTTPMetadataProvider httpMetadataProvider = new HTTPMetadataProvider(new Timer(true), httpClient(), idpUrl);
httpMetadataProvider.setParserPool(parserPool());
//ExtendedMetadata em = new ExtendedMetadata(); //Attempt to explicitly add cert alias to extended metadata
//em.setAlias(keystoreCertAlias);
//em.setSigningKey("*.product.company.com");
ExtendedMetadataDelegate extendedMetadataDelegate = new ExtendedMetadataDelegate(httpMetadataProvider);//, em);
extendedMetadataDelegate.setMetadataTrustCheck(false);
return new CachingMetadataManager(ImmutableList.<MetadataProvider>of(extendedMetadataDelegate));
}
这是错误:
2020-05-27 17:02:27.552 ERROR 41402 --- [ main] o.s.s.s.t.MetadataCredentialResolver : PKIX path construction failed for untrusted credential: [subjectName='CN=*.product.company.com,O=Company,L=Location,ST=state,C=US']: unable to find valid certification path to requested target
2020-05-27 17:02:27.556 INFO 41402 --- [ main] o.a.c.httpclient.HttpMethodDirector : I/O exception (javax.net.ssl.SSLPeerUnverifiedException) caught when processing request: SSL peer failed hostname validation for name: null
2020-05-27 17:02:27.557 INFO 41402 --- [ main] o.a.c.httpclient.HttpMethodDirector : Retrying request
...
javax.net.ssl.SSLPeerUnverifiedException: SSL peer failed hostname validation for name: null
at org.opensaml.ws.soap.client.http.TLSProtocolSocketFactory.verifyHostname(TLSProtocolSocketFactory.java:233) ~[openws-1.5.4.jar:na]
at org.opensaml.ws.soap.client.http.TLSProtocolSocketFactory.createSocket(TLSProtocolSocketFactory.java:186) ~[openws-1.5.4.jar:na]
at org.springframework.security.saml.trust.httpclient.TLSProtocolSocketFactory.createSocket(TLSProtocolSocketFactory.java:97) ~[spring-security-saml2-core-1.0.10.RELEASE.jar:1.0.10.RELEASE]
at org.apache.commons.httpclient.HttpConnection.open(HttpConnection.java:707) ~[commons-httpclient-3.1.jar:na]
at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$HttpConnectionAdapter.open(MultiThreadedHttpConnectionManager.java:1361) ~[commons-httpclient-3.1.jar:na]
at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:387) ~[commons-httpclient-3.1.jar:na]
at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171) ~[commons-httpclient-3.1.jar:na]
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397) ~[commons-httpclient-3.1.jar:na]
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323) ~[commons-httpclient-3.1.jar:na]
at org.opensaml.saml2.metadata.provider.HTTPMetadataProvider.fetchMetadata(HTTPMetadataProvider.java:250) ~[opensaml-2.6.4.jar:na]
at org.opensaml.saml2.metadata.provider.AbstractReloadingMetadataProvider.refresh(AbstractReloadingMetadataProvider.java:255) [opensaml-2.6.4.jar:na]
at org.opensaml.saml2.metadata.provider.AbstractReloadingMetadataProvider.doInitialization(AbstractReloadingMetadataProvider.java:236) [opensaml-2.6.4.jar:na]
at org.opensaml.saml2.metadata.provider.AbstractMetadataProvider.initialize(AbstractMetadataProvider.java:407) [opensaml-2.6.4.jar:na]
at org.springframework.security.saml.metadata.ExtendedMetadataDelegate.initialize(ExtendedMetadataDelegate.java:167) [spring-security-saml2-core-1.0.10.RELEASE.jar:1.0.10.RELEASE]
at com.company.product.ProductApplication.main(ProductApplication.java:10) ~[classes/:na]
像这样创建 JKS 密钥库(使用附加密钥):
keytool -genkeypair \
-v \
-keystore product.jks \
-storepass hidden \
-alias product \
-dname 'CN=localhost, OU=Company, O=Org, L=Loc, ST=State, C=US' \
-keypass hidden \
-keyalg RSA \
-keysize 2048 \
-sigalg SHA256withRSA
我也包含了证书:
Signature trust establishment failed for SAML metadata entry
我的 IDP 提供的证书包含在我的密钥库中:
keytool -importcert \
-file cert.pem \
-keystore product.jks \
-alias idp-server \
-storepass hidden
我已经尝试了以下所有门票:
试图在 KeyManager 中添加密码中包含的证书(我将证书密码设置为密钥库密码,因为证书没有)
在 TLSProtocolConfigurer.setSslHostnameVerification 中尝试了 allowAll,在 TLSProtocolSocketFactory 构造函数中尝试了 defaultAndLocalhost。
信任检查已被禁用:
extendedMetadataDelegate.setMetadataTrustCheck(假);
Signature trust establishment failed for SAML metadata entry
尝试在附加到委托的 ExtendedMetadata 中设置证书的别名:
ExtendedMetadata em = new ExtendedMetadata();
em.setAlias(keystoreCertAlias);
em.setSigningKey("*.product.company.com"); //This is obfuscated
ExtendedMetadataDelegate extendedMetadataDelegate = new ExtendedMetadataDelegate(httpMetadataProvider, em);
我倾向于使用证书错误地设置密钥库。我尝试将 PEM 转换为 crt 和 cer 以查看它是否会有所不同,但没有。我可以向您保证,这是 IDP 证书而不是域证书(仅供参考,这是故意不使用 cacerts,而是在密钥库中包含证书以使用 HTTPS)。
非常感谢ideas/help!
谢谢。
为了解决这个问题,我删除了 tlsProtocolConfigurer
bean 和所有与之关联的 bean。我不完全确定为什么样本包含它,因为它在没有它的情况下与 HTTPS(和 localhost)一起工作得很好。
注意:
我假设实际问题是 tlsProtocolConfigurer 没有在密钥库中找到证书,但对于我的应用程序来说,整个 bean 不是必需的,所以它成为了一个有争议的问题。
运行 在 Java 中设置 SAML 2.0 的这个问题 Spring 使用最新的库启动。
这里有一些相关代码,但如果还有其他帮助,请告诉我:
@Bean
public KeyManager keyManager()
{
return new JKSKeyManager(keyStoreResource, keystorePassword, ImmutableMap.of(keystoreKeyAlias, keystorePrivateKeyPassword), keystoreKeyAlias);
}
@Bean
public SAMLDiscovery samlIDPDiscovery()
{
return new SAMLDiscovery();
}
@Bean
public MetadataDisplayFilter metadataDisplayFilter()
{
return new MetadataDisplayFilter();
}
@Bean
public TLSProtocolConfigurer tlsProtocolConfigurer()
{
TLSProtocolConfigurer t = new TLSProtocolConfigurer();
//t.setSslHostnameVerification("allowAll");
return t;
}
// Configure TLSProtocolConfigurer
@Bean
public ProtocolSocketFactory protocolSocketFactory()
{
//return new TLSProtocolSocketFactory(keyManager(), null, "defaultAndLocalhost");
return new TLSProtocolSocketFactory(keyManager(), null, "default");
}
@Bean
public Protocol protocol()
{
return new Protocol("https", protocolSocketFactory(), 443);
}
@Bean
public MethodInvokingFactoryBean socketFactoryInitialization()
{
MethodInvokingFactoryBean methodInvokingFactoryBean = new MethodInvokingFactoryBean();
methodInvokingFactoryBean.setTargetClass(Protocol.class);
methodInvokingFactoryBean.setTargetMethod("registerProtocol");
methodInvokingFactoryBean.setArguments(new Object[] { "https", protocol() });
return methodInvokingFactoryBean;
}
@Bean
public CachingMetadataManager metadata() throws MetadataProviderException
{
HTTPMetadataProvider httpMetadataProvider = new HTTPMetadataProvider(new Timer(true), httpClient(), idpUrl);
httpMetadataProvider.setParserPool(parserPool());
//ExtendedMetadata em = new ExtendedMetadata(); //Attempt to explicitly add cert alias to extended metadata
//em.setAlias(keystoreCertAlias);
//em.setSigningKey("*.product.company.com");
ExtendedMetadataDelegate extendedMetadataDelegate = new ExtendedMetadataDelegate(httpMetadataProvider);//, em);
extendedMetadataDelegate.setMetadataTrustCheck(false);
return new CachingMetadataManager(ImmutableList.<MetadataProvider>of(extendedMetadataDelegate));
}
这是错误:
2020-05-27 17:02:27.552 ERROR 41402 --- [ main] o.s.s.s.t.MetadataCredentialResolver : PKIX path construction failed for untrusted credential: [subjectName='CN=*.product.company.com,O=Company,L=Location,ST=state,C=US']: unable to find valid certification path to requested target
2020-05-27 17:02:27.556 INFO 41402 --- [ main] o.a.c.httpclient.HttpMethodDirector : I/O exception (javax.net.ssl.SSLPeerUnverifiedException) caught when processing request: SSL peer failed hostname validation for name: null
2020-05-27 17:02:27.557 INFO 41402 --- [ main] o.a.c.httpclient.HttpMethodDirector : Retrying request
...
javax.net.ssl.SSLPeerUnverifiedException: SSL peer failed hostname validation for name: null
at org.opensaml.ws.soap.client.http.TLSProtocolSocketFactory.verifyHostname(TLSProtocolSocketFactory.java:233) ~[openws-1.5.4.jar:na]
at org.opensaml.ws.soap.client.http.TLSProtocolSocketFactory.createSocket(TLSProtocolSocketFactory.java:186) ~[openws-1.5.4.jar:na]
at org.springframework.security.saml.trust.httpclient.TLSProtocolSocketFactory.createSocket(TLSProtocolSocketFactory.java:97) ~[spring-security-saml2-core-1.0.10.RELEASE.jar:1.0.10.RELEASE]
at org.apache.commons.httpclient.HttpConnection.open(HttpConnection.java:707) ~[commons-httpclient-3.1.jar:na]
at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$HttpConnectionAdapter.open(MultiThreadedHttpConnectionManager.java:1361) ~[commons-httpclient-3.1.jar:na]
at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:387) ~[commons-httpclient-3.1.jar:na]
at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171) ~[commons-httpclient-3.1.jar:na]
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397) ~[commons-httpclient-3.1.jar:na]
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323) ~[commons-httpclient-3.1.jar:na]
at org.opensaml.saml2.metadata.provider.HTTPMetadataProvider.fetchMetadata(HTTPMetadataProvider.java:250) ~[opensaml-2.6.4.jar:na]
at org.opensaml.saml2.metadata.provider.AbstractReloadingMetadataProvider.refresh(AbstractReloadingMetadataProvider.java:255) [opensaml-2.6.4.jar:na]
at org.opensaml.saml2.metadata.provider.AbstractReloadingMetadataProvider.doInitialization(AbstractReloadingMetadataProvider.java:236) [opensaml-2.6.4.jar:na]
at org.opensaml.saml2.metadata.provider.AbstractMetadataProvider.initialize(AbstractMetadataProvider.java:407) [opensaml-2.6.4.jar:na]
at org.springframework.security.saml.metadata.ExtendedMetadataDelegate.initialize(ExtendedMetadataDelegate.java:167) [spring-security-saml2-core-1.0.10.RELEASE.jar:1.0.10.RELEASE]
at com.company.product.ProductApplication.main(ProductApplication.java:10) ~[classes/:na]
像这样创建 JKS 密钥库(使用附加密钥):
keytool -genkeypair \
-v \
-keystore product.jks \
-storepass hidden \
-alias product \
-dname 'CN=localhost, OU=Company, O=Org, L=Loc, ST=State, C=US' \
-keypass hidden \
-keyalg RSA \
-keysize 2048 \
-sigalg SHA256withRSA
我也包含了证书: Signature trust establishment failed for SAML metadata entry 我的 IDP 提供的证书包含在我的密钥库中:
keytool -importcert \
-file cert.pem \
-keystore product.jks \
-alias idp-server \
-storepass hidden
我已经尝试了以下所有门票:
在 TLSProtocolConfigurer.setSslHostnameVerification 中尝试了 allowAll,在 TLSProtocolSocketFactory 构造函数中尝试了 defaultAndLocalhost。
Signature trust establishment failed for SAML metadata entry 尝试在附加到委托的 ExtendedMetadata 中设置证书的别名:
ExtendedMetadata em = new ExtendedMetadata();
em.setAlias(keystoreCertAlias);
em.setSigningKey("*.product.company.com"); //This is obfuscated
ExtendedMetadataDelegate extendedMetadataDelegate = new ExtendedMetadataDelegate(httpMetadataProvider, em);
我倾向于使用证书错误地设置密钥库。我尝试将 PEM 转换为 crt 和 cer 以查看它是否会有所不同,但没有。我可以向您保证,这是 IDP 证书而不是域证书(仅供参考,这是故意不使用 cacerts,而是在密钥库中包含证书以使用 HTTPS)。
非常感谢ideas/help! 谢谢。
为了解决这个问题,我删除了 tlsProtocolConfigurer
bean 和所有与之关联的 bean。我不完全确定为什么样本包含它,因为它在没有它的情况下与 HTTPS(和 localhost)一起工作得很好。
注意: 我假设实际问题是 tlsProtocolConfigurer 没有在密钥库中找到证书,但对于我的应用程序来说,整个 bean 不是必需的,所以它成为了一个有争议的问题。