【发布时间】:2014-09-23 10:39:56
【问题描述】:
我想使用 https 协议从网络导入一些元数据:
@Bean
public HTTPMetadataProvider ssoCircleMetadataProvider()
throws MetadataProviderException {
String metadataURL = "https://idp.ssocircle.com/idp-meta.xml";
final Timer backgroundTaskTimer = new Timer(true);
HTTPMetadataProvider provider = new HTTPMetadataProvider(
backgroundTaskTimer, httpClient(), metadataURL);
provider.setParserPool(parserPool());
return provider;
}
通过阅读documentation,我发现了这一步:
默认情况下,使用基于 HTTP 的提供程序加载元数据 HTTPS 执行在您的 JDK 中配置的信任验证。如果 你想在你的 keyStore 中使用证书,添加以下内容 更改 HTTP 客户端使用的 socketFactory 的 bean:
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetClass" value="org.apache.commons.httpclient.protocol.Protocol"/>
<property name="targetMethod" value="registerProtocol"/>
<property name="arguments">
<list>
<value>https</value>
<bean class="org.apache.commons.httpclient.protocol.Protocol">
<constructor-arg value="https"/>
<constructor-arg>
<bean class="org.springframework.security.saml.trust.httpclient.TLSProtocolSocketFactory"/>
</constructor-arg>
<constructor-arg value="443"/>
</bean>
</list>
</property>
</bean>
在Java Config中转换,变成:
@Bean
public Protocol httpClientProtocol() {
org.springframework.security.saml.trust.httpclient.TLSProtocolSocketFactory factory =
new org.springframework.security.saml.trust.httpclient.TLSProtocolSocketFactory();
Protocol httpClientProtocol = new Protocol ("https", factory, 443);
return httpClientProtocol;
}
@Bean
public MethodInvokingFactoryBean methodInvokingFactoryBean() {
MethodInvokingFactoryBean methodInvokingFactoryBean = new MethodInvokingFactoryBean();
methodInvokingFactoryBean.setTargetClass(Protocol.class);
methodInvokingFactoryBean.setTargetMethod("registerProtocol");
Object[] args = {"https", httpClientProtocol()};
methodInvokingFactoryBean.setArguments(args);
return methodInvokingFactoryBean;
}
但未找到 org.springframework.security.saml.trust.httpclient.TLSProtocolSocketFactory 类结果。我正在使用 Spring SAML 的 1.0.0-RC2 版本。
我做错了吗?
如何修复此错误并根据需要加载元数据?
更新
通过使用 SNAPSHOT 存储库,我可以使用 TLSProtocolSocketFactory 类。 我已将 SSOCircle 的证书导入到我的密钥库中,但尽管如此,应用程序仍返回如下错误:
[2014-07-31 17:33:27.596] boot - 11800 ERROR [localhost-startStop-1] --- HTTPMetadataProvider: Error retrieving metadata from https://idp.ssocircle.com/idp-meta.xml
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
更新 2
我已根据您的建议修复了我的代码。我已将所有证书导入密钥库,但在启动时应用程序返回此错误:
[2014-08-01 10:02:38.961] boot - 14704 DEBUG [localhost-startStop-1] --- BasicX509CredentialNameEvaluator: Supplied trusted names are null or empty, skipping name evaluation
[2014-08-01 10:02:38.962] boot - 14704 DEBUG [localhost-startStop-1] --- MetadataCredentialResolver: Attempting PKIX path validation on untrusted credential: [subjectName='CN=ADFS Signing - ststest-vdenotarisnet.vdenotaris.it']
[2014-08-01 10:02:39.028] boot - 14704 ERROR [localhost-startStop-1] --- MetadataCredentialResolver: PKIX path construction failed for untrusted credential: [subjectName='CN=ADFS Signing - ststest-vdenotarisnet.vdenotaris.it']: unable to find valid certification path to requested target
[2014-08-01 10:02:39.028] boot - 14704 DEBUG [localhost-startStop-1] --- PKIXSignatureTrustEngine: Signature trust could not be established via PKIX validation of signing credential
[2014-08-01 10:02:39.028] boot - 14704 DEBUG [localhost-startStop-1] --- BaseSignatureTrustEngine: Failed to establish trust of KeyInfo-derived credential
[2014-08-01 10:02:39.028] boot - 14704 DEBUG [localhost-startStop-1] --- BaseSignatureTrustEngine: Failed to verify signature and/or establish trust using any KeyInfo-derived credentials
[2014-08-01 10:02:39.029] boot - 14704 DEBUG [localhost-startStop-1] --- PKIXSignatureTrustEngine: PKIX validation of signature failed, unable to resolve valid and trusted signing key
[2014-08-01 10:02:39.029] boot - 14704 ERROR [localhost-startStop-1] --- SignatureValidationFilter: Signature trust establishment failed for metadata entry http://ststest.vdenotaris.local/adfs/services/trust
[2014-08-01 10:02:39.031] boot - 14704 ERROR [localhost-startStop-1] --- AbstractReloadingMetadataProvider: Error filtering metadata from https://ststest.vdenotaris.local/FederationMetadata/2007-06/FederationMetadata.xml
org.opensaml.saml2.metadata.provider.FilterException: Signature trust establishment failed for metadata entry
请注意,使用的证书是由 GoDaddy 验证的。
【问题讨论】:
-
使用 -Djavax.net.debug=all 启动您的应用程序,让我们看看它的含义 - 日志跟踪应包含有关 PKIX 失败原因的更多详细信息。你的证书有没有可能过期?请仔细检查您是否已将正确的密钥导入 samlKeystore.jks
-
顺便说一句,我已经简化了配置,一旦你更新到更高版本,你唯一需要做的就是包含类 org.springframework.security.saml.trust.httpclient.TLSProtocolConfigurer 的 bean
-
导入是正确的,我很确定。证书仍然有效。我会尽快按照建议提供 javax.net 调试选项来检查应用程序。
-
我确定现在导入是正确的,这不是我的意思 - 我制作了 TLSProtocolConfigurer 来为将来尝试配置相同的人简化它,并想要警告您更新后必须重新配置。
-
它将在明天的夜间构建中。
标签: java spring spring-security saml spring-saml