java - 使用 Spring SAML 从 https 加载元数据

标签 java spring spring-security saml spring-saml

我想使用 https 协议(protocol)从网络导入一些元数据:

@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 ,我找到了这一步:

By default loading of metadata using the HTTP-based provider over HTTPS performs trust verification configured in your JDK. In case you'd like to use certificates in your keyStore, add the following bean which changes the socketFactory used by the HTTP Client:

<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未找到类(class)成绩。我使用的版本1.0.0-RC2 Spring SAML

我做错了什么吗?

如何修复此错误并根据需要加载元数据?


更新

通过使用 SNAPSHOT 存储库,我可以使用 TLSProtocolSocketFactory 类。 我已将 SSOCircle 的证书导入到我的 keystore 中,但尽管如此,应用程序仍返回错误,如下所示:

[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

我已根据您的建议修复了我的代码。我已将所有证书导入 keystore ,但在启动时应用程序返回此错误:

[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 验证。

最佳答案

TLSProtocolSocketFactory 类仅在主干中可用,并且将成为 1.0.0.FINAL 的一部分。 RC2 中唯一的选择是将 key 添加到 JDK 的 keystore 。

更新:

此存储库中提供了 Spring SAML 的快照版本:

<repository>
  <releases>
    <enabled>false</enabled>
  </releases>
  <snapshots>
    <enabled>true</enabled>
  </snapshots>
  <id>com.springsource.repository.maven.snapshot</id>
  <name>SpringSource Enterprise Bundle Maven Repository - SpringSource Snapshot Releases</name>
  <url>http://maven.springframework.org/snapshot</url>
</repository>

您可能需要阅读“新增内容”一章,其中列出了自 RC2 以来的更改,其中一些更改涉及向后兼容性。

另一个更新:

您的初始化错误,TLSFactory 需要作为 bean 启动,您可能还需要 MetadataManager 中的依赖项。

@Bean
public ProtocolSocketFactory socketFactory() {
    return new TLSProtocolSocketFactory();
}

@Bean
public Protocol socketFactoryProtocol() {
    return new Protocol("https", socketFactory(), 443);
}

@Bean
public MethodInvokingFactoryBean socketFactoryInitialization() {
    MethodInvokingFactoryBean methodInvokingFactoryBean = new MethodInvokingFactoryBean();
    methodInvokingFactoryBean.setTargetClass(Protocol.class);
    methodInvokingFactoryBean.setTargetMethod("registerProtocol");
    Object[] args = {"https", socketFactoryProtocol()};
    methodInvokingFactoryBean.setArguments(args);
    return methodInvokingFactoryBean;
}

@Bean
@Qualifier("metadata")
@DependsOn("socketFactoryInitialization")
public CachingMetadataManager metadata() throws MetadataProviderException, IOException     {
  ...
}

关于java - 使用 Spring SAML 从 https 加载元数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25059684/

相关文章:

Java解析JSON路径值到变量

spring - 使用 Spring LDAP Repository 的多个 LDAP 存储库

grails - Grails安全插件自定义重定向

java - 使用 Spring Security 进行 JWT 解码

java - 为什么 Spring Security 的 BindAuthenticator 需要用户读取权限?

java - pg_hba.conf 中没有条目

java - 公开使用的 Vector 中的私有(private)类

java - 循环多个协同工作的扫描仪输入,直到出现特定输入

spring - 如何使用 Tomcat + Spring Security 对静态内容强制执行 HTTPS

java - 您对 Spring MVC 应用程序中的服务层使用什么命名约定?