正确的SAML TLSProtocolSocketFactory配置

时间:2016-04-18 09:36:34

标签: java spring spring-security saml

我使用Spring SAML来验证用户身份 默认情况下,SAML实现每小时刷新一次元数据 初始运行org.opensaml.saml2.metadata.provider.AbstractReloadingMetadataProvider.refresh()有效,但所有后续调用(由计时器调用)都失败:

INFO: org.apache.commons.httpclient.HttpMethodDirector - Retrying request
ERROR: org.springframework.security.saml.trust.MetadataCredentialResolver - PKIX path construction failed for untrusted credential: [subjectName='CONTENT_REMOVED_FOR_STACKOVERFLOW']: unable to find valid certification path to requested target
ERROR: org.opensaml.saml2.metadata.provider.HTTPMetadataProvider - Error retrieving metadata from https://HOSTNAME/PATH?cmd=metadata
javax.net.ssl.SSLPeerUnverifiedException: SSL peer failed hostname validation for name: null
    at org.opensaml.ws.soap.client.http.TLSProtocolSocketFactory.verifyHostname(TLSProtocolSocketFactory.java:233)
    at org.opensaml.ws.soap.client.http.TLSProtocolSocketFactory.createSocket(TLSProtocolSocketFactory.java:194)
    at org.springframework.security.saml.trust.httpclient.TLSProtocolSocketFactory.createSocket(TLSProtocolSocketFactory.java:97)
    at org.apache.commons.httpclient.HttpConnection.open(HttpConnection.java:707)
    at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:387)
    at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171)
    at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
    at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323)
    at org.opensaml.saml2.metadata.provider.HTTPMetadataProvider.fetchMetadata(HTTPMetadataProvider.java:250)
    at org.opensaml.saml2.metadata.provider.AbstractReloadingMetadataProvider.refresh(AbstractReloadingMetadataProvider.java:260)
    at org.opensaml.saml2.metadata.provider.AbstractReloadingMetadataProvider$RefreshMetadataTask.run(AbstractReloadingMetadataProvider.java:521)
    at java.util.TimerThread.mainLoop(Timer.java:555)
    at java.util.TimerThread.run(Timer.java:505)
DEBUG: org.opensaml.saml2.metadata.provider.AbstractReloadingMetadataProvider - Error occurred while attempting to refresh metadata from 'https://HOSTNAME/PATH?cmd=metadata'
org.opensaml.saml2.metadata.provider.MetadataProviderException: Error retrieving metadata from https://HOSTNAME/PATH?cmd=metadata
    at org.opensaml.saml2.metadata.provider.HTTPMetadataProvider.fetchMetadata(HTTPMetadataProvider.java:274)
    at org.opensaml.saml2.metadata.provider.AbstractReloadingMetadataProvider.refresh(AbstractReloadingMetadataProvider.java:260)
    at org.opensaml.saml2.metadata.provider.AbstractReloadingMetadataProvider$RefreshMetadataTask.run(AbstractReloadingMetadataProvider.java:521)
    at java.util.TimerThread.mainLoop(Timer.java:555)
    at java.util.TimerThread.run(Timer.java:505)
Caused by: javax.net.ssl.SSLPeerUnverifiedException: SSL peer failed hostname validation for name: null
    at org.opensaml.ws.soap.client.http.TLSProtocolSocketFactory.verifyHostname(TLSProtocolSocketFactory.java:233)
    at org.opensaml.ws.soap.client.http.TLSProtocolSocketFactory.createSocket(TLSProtocolSocketFactory.java:194)
    at org.springframework.security.saml.trust.httpclient.TLSProtocolSocketFactory.createSocket(TLSProtocolSocketFactory.java:97)
    at org.apache.commons.httpclient.HttpConnection.open(HttpConnection.java:707)
    at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:387)
    at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171)
    at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
    at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323)
    at org.opensaml.saml2.metadata.provider.HTTPMetadataProvider.fetchMetadata(HTTPMetadataProvider.java:250)
    ... 4 common frames omitted

我将其追溯到org.springframework.security.saml.trust.httpclient.TLSProtocolConfigurer bean。

<bean class="org.springframework.security.saml.trust.httpclient.TLSProtocolConfigurer">
    <property name="sslHostnameVerification" value="default"/>
    <property name="keyManager" ref="keyManager"/>
</bean>

afterPropertiesSet()中,此bean会覆盖之前注册的(org.opensaml.ws.soap.client.http.TLSProtocolSocketFactory)https协议(org.apache.commons.httpclient.protocol.Protocol) 与org.springframework.security.saml.trust.httpclient.TLSProtocolSocketFactory

因此,第一个呼叫使用org.opensaml.ws.soap.client.http.TLSProtocolSocketFactory,所有定时器调用都使用org.springframework.security.saml.trust.httpclient.TLSProtocolSocketFactory失败。

如果我从弹簧配置中删除TLSProtocolConfigurer,一切正常。问题是,我可以不破坏任何东西吗? 这是我应该报告的错误吗?

1 个答案:

答案 0 :(得分:0)

例外情况说,它无法验证证书中定义的主机名。因此,您的Timer在主机上执行,其名称与证书中的名称不匹配。所以这不是一个错误。