有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

我想使用https协议从web导入一些元数据:

@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配置中转换时,它将变成:

@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

我做错什么了吗

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


更新

通过使用快照存储库,我能够使用TLSProtocolSocketFactory类。 我已将SSOCIRCE证书导入密钥库,但尽管如此,应用程序仍返回一个错误,如下所示:

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


共 (1) 个答案

  1. # 1 楼答案

    TLSProtocolSocketFactory类仅在主干中可用,并且将是1.0.0的一部分。最终的RC2中唯一的选择是向JDK的密钥库添加密钥

    更新:

    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     {
      ...
    }