2016-02-24 113 views
1

我們將Salesforce設置爲IDP,而我們的應用程序使用Spring SAML擴展名爲SP。但是,我們收到錯誤'SSL對等失敗主機名驗證的名稱:null'javax.net.ssl.SSLPeerUnverifiedException:名稱的SSL對等失敗主機名驗證:null

2016-02-24 11:51:18 [localhost-startStop-1 ] ERROR o.s.s.s.t.MetadataCredentialResolver         : 111 - PKIX path construction failed for untrusted credential: [subjectName='CN=*.my.salesforce.com,OU=Applications,O=Salesforce.com\, Inc,L=San Francisco,ST=California,C=US']: unable to find valid certification path to requested target 
2016-02-24 11:51:18 [localhost-startStop-1 ] INFO o.a.c.h.HttpMethodDirector           : 439 - I/O exception (javax.net.ssl.SSLPeerUnverifiedException) caught when processing request: SSL peer failed hostname validation for name: null 
2016-02-24 11:51:18 [localhost-startStop-1 ] INFO o.a.c.h.HttpMethodDirector           : 445 - Retrying request 
2016-02-24 11:51:18 [localhost-startStop-1 ] ERROR o.s.s.s.t.MetadataCredentialResolver         : 111 - PKIX path construction failed for untrusted credential: [subjectName='CN=*.my.salesforce.com,OU=Applications,O=Salesforce.com\, Inc,L=San Francisco,ST=California,C=US']: unable to find valid certification path to requested target 
2016-02-24 11:51:18 [localhost-startStop-1 ] INFO o.a.c.h.HttpMethodDirector           : 439 - I/O exception (javax.net.ssl.SSLPeerUnverifiedException) caught when processing request: SSL peer failed hostname validation for name: null 
2016-02-24 11:51:18 [localhost-startStop-1 ] INFO o.a.c.h.HttpMethodDirector           : 445 - Retrying request 
2016-02-24 11:51:19 [localhost-startStop-1 ] ERROR o.s.s.s.t.MetadataCredentialResolver         : 111 - PKIX path construction failed for untrusted credential: [subjectName='CN=*.my.salesforce.com,OU=Applications,O=Salesforce.com\, Inc,L=San Francisco,ST=California,C=US']: unable to find valid certification path to requested target 
2016-02-24 11:51:19 [localhost-startStop-1 ] INFO o.a.c.h.HttpMethodDirector           : 439 - I/O exception (javax.net.ssl.SSLPeerUnverifiedException) caught when processing request: SSL peer failed hostname validation for name: null 
2016-02-24 11:51:19 [localhost-startStop-1 ] INFO o.a.c.h.HttpMethodDirector           : 445 - Retrying request 
2016-02-24 11:51:19 [localhost-startStop-1 ] ERROR o.s.s.s.t.MetadataCredentialResolver         : 111 - PKIX path construction failed for untrusted credential: [subjectName='CN=*.my.salesforce.com,OU=Applications,O=Salesforce.com\, Inc,L=San Francisco,ST=California,C=US']: unable to find valid certification path to requested target 
2016-02-24 11:51:19 [localhost-startStop-1 ] ERROR o.o.s.m.p.HTTPMetadataProvider          : 273 - Error retrieving metadata from https://flexsaml-dev-ed.my.salesforce.com/.well-known/samlidp/RevitasCCSpring.xml 
javax.net.ssl.SSLPeerUnverifiedException: SSL peer failed hostname validation for name: null 

這是我們的SAML配置類。

@Autowired 
private SAMLUserDetailsServiceImpl samlUserDetailsServiceImpl; 

@Autowired 
private ResourceLoader resourceLoader; 

@Autowired 
private Environment env; 

@Autowired 
private AuthenticationUtilService authenticationUtilService; 

// Initialization of the velocity engine 
@Bean 
public VelocityEngine velocityEngine() { 
    return VelocityFactory.getEngine(); 
} 

// XML parser pool needed for OpenSAML parsing 
@Bean(initMethod = "initialize") 
public StaticBasicParserPool parserPool() { 
    return new StaticBasicParserPool(); 
} 

@Bean(name = "parserPoolHolder") 
public ParserPoolHolder parserPoolHolder() { 
    return new ParserPoolHolder(); 
} 

// Bindings, encoders and decoders used for creating and parsing messages 
@Bean 
public MultiThreadedHttpConnectionManager multiThreadedHttpConnectionManager() { 
    return new MultiThreadedHttpConnectionManager(); 
} 

@Bean 
public HttpClient httpClient() { 
    return new HttpClient(multiThreadedHttpConnectionManager()); 
} 

// SAML Authentication Provider responsible for validating of received SAML 
// messages 
@Bean 
public SAMLAuthenticationProvider samlAuthenticationProvider() { 
    SAMLAuthenticationProvider samlAuthenticationProvider = new SAMLAuthenticationProvider(); 
    samlAuthenticationProvider.setUserDetails(samlUserDetailsServiceImpl); 
    samlAuthenticationProvider.setForcePrincipalAsString(false); 
    return samlAuthenticationProvider; 
} 

// Provider of default SAML Context 
@Bean 
public SAMLContextProviderImpl contextProvider() { 
    return new SAMLContextProviderImpl(); 
} 

// Initialization of OpenSAML library 
@Bean 
public static SAMLBootstrap sAMLBootstrap() { 
    return new SAMLBootstrap(); 
} 

// Logger for SAML messages and events 
@Bean 
public SAMLDefaultLogger samlLogger() { 
    return new SAMLDefaultLogger(); 
} 

// SAML 2.0 WebSSO Assertion Consumer 
@Bean 
public WebSSOProfileConsumer webSSOprofileConsumer() { 
    WebSSOProfileConsumerImpl webSSOProfileConsumer = new WebSSOProfileConsumerImpl(); 
    webSSOProfileConsumer.setResponseSkew(6000000); 
    return webSSOProfileConsumer; 
} 

// SAML 2.0 Holder-of-Key WebSSO Assertion Consumer 
@Bean 
public WebSSOProfileConsumerHoKImpl hokWebSSOprofileConsumer() { 
    return new WebSSOProfileConsumerHoKImpl(); 
} 

// SAML 2.0 Web SSO profile 
@Bean 
public WebSSOProfile webSSOprofile() { 
    return new WebSSOProfileImpl(); 
} 

// SAML 2.0 Holder-of-Key Web SSO profile 
@Bean 
public WebSSOProfileConsumerHoKImpl hokWebSSOProfile() { 
    return new WebSSOProfileConsumerHoKImpl(); 
} 

// SAML 2.0 ECP profile 
@Bean 
public WebSSOProfileECPImpl ecpprofile() { 
    return new WebSSOProfileECPImpl(); 
} 

@Bean 
public SingleLogoutProfile logoutprofile() { 
    SingleLogoutProfileImpl singleLogoutProfile = new SingleLogoutProfileImpl(); 
    singleLogoutProfile.setResponseSkew(6000000); 
    return singleLogoutProfile; 
} 

// Central storage of cryptographic keys 
@Bean 
public KeyManager keyManager() { 
    Resource storeFile = null; 
    if (StringUtils.isEmpty(env.getProperty("saml.keystore.file"))) { 
     storeFile = resourceLoader 
       .getResource("file:" + env.getProperty("saml.keystore.file")); 
    } else { 
     storeFile = resourceLoader.getResource("classpath:/saml/samlKeystore.jks"); 
    } 
    String storePass = "nalle123"; 
    Map<String, String> passwords = new HashMap<String, String>(); 
    passwords.put("apollo", "nalle123"); 
    String defaultKey = "apollo"; 
    return new JKSKeyManager(storeFile, storePass, passwords, defaultKey); 
} 

// Setup TLS Socket Factory 
@Bean 
public TLSProtocolConfigurer tlsProtocolConfigurer() { 
    TLSProtocolConfigurer tlsProtocolConfigurer = new TLSProtocolConfigurer(); 
    tlsProtocolConfigurer.setSslHostnameVerification("allowAll"); 
    return tlsProtocolConfigurer; 
} 

@Bean 
public ProtocolSocketFactory socketFactory() { 
    return new TLSProtocolSocketFactory(keyManager(), null, "default"); 
} 

@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 
public WebSSOProfileOptions defaultWebSSOProfileOptions() { 
    WebSSOProfileOptions webSSOProfileOptions = new WebSSOProfileOptions(); 
    webSSOProfileOptions.setIncludeScoping(false); 
    return webSSOProfileOptions; 
} 

// Entry point to initialize authentication, default values taken from 
// properties file 
@Bean 
public SAMLEntryPoint samlEntryPoint() { 
    SAMLEntryPoint samlEntryPoint = new SAMLEntryPoint(); 
    samlEntryPoint.setDefaultProfileOptions(defaultWebSSOProfileOptions()); 
    return samlEntryPoint; 
} 

// Setup advanced info about metadata 
@Bean 
public ExtendedMetadata extendedMetadata() { 
    ExtendedMetadata extendedMetadata = new ExtendedMetadata(); 
    extendedMetadata.setIdpDiscoveryEnabled(true); 
    extendedMetadata.setSignMetadata(false); 
    return extendedMetadata; 
} 

// IDP Discovery Service 
@Bean 
public SAMLDiscovery samlIDPDiscovery() { 
    SAMLDiscovery idpDiscovery = new SAMLDiscovery(); 
    idpDiscovery.setIdpSelectionPath("/saml/idpSelection"); 
    return idpDiscovery; 
} 

@Bean 
@Qualifier("idp-local") 
public ExtendedMetadataDelegate localIdpExtendedMetadataProvider() 
     throws MetadataProviderException { 
    File file = null; 
    try { 
     file = resourceLoader.getResource("classpath:/saml/metadata/idp.xml").getFile(); 
    } catch (IOException e) { 
     theLogger.error("File doesn't exist..."); 
     return null; 
    } 

    Timer backgroundTaskTimer = new Timer(true); 
    FilesystemMetadataProvider filesystemMetadataProvider = new FilesystemMetadataProvider(
      backgroundTaskTimer, file); 
    filesystemMetadataProvider.setParserPool(parserPool()); 
    ExtendedMetadataDelegate extendedMetadataDelegate = 
      new ExtendedMetadataDelegate(filesystemMetadataProvider, extendedMetadata()); 
    extendedMetadataDelegate.setMetadataTrustCheck(true); 
    extendedMetadataDelegate.setMetadataRequireSignature(false); 
    return extendedMetadataDelegate; 
} 

@Bean 
@Qualifier("idp-sfdcHttp") 
public ExtendedMetadataDelegate sfdcHttpExtendedMetadataProvider() 
     throws MetadataProviderException { 
    String sfdcMetadaURL = "https://flexsaml-dev-ed.my.salesforce.com/.well-known/samlidp/RevitasCCSpring.xml"; 
    Timer backgroundTaskTimer = new Timer(true); 
    HTTPMetadataProvider httpMetadataProvider = new HTTPMetadataProvider(
      backgroundTaskTimer, httpClient(), sfdcMetadaURL); 
    httpMetadataProvider.setParserPool(parserPool()); 
    ExtendedMetadataDelegate extendedMetadataDelegate = 
      new ExtendedMetadataDelegate(httpMetadataProvider, extendedMetadata()); 
    extendedMetadataDelegate.setMetadataTrustCheck(false); 
    extendedMetadataDelegate.setMetadataRequireSignature(false); 
    return extendedMetadataDelegate; 
} 

// IDP Metadata configuration - paths to metadata of IDPs in circle of trust 
// is here 
// Do no forget to call iniitalize method on providers 
@Bean 
@Qualifier("metadata") 
public CachingMetadataManager metadata() throws MetadataProviderException { 
    List<MetadataProvider> providers = new ArrayList<MetadataProvider>(); 
    providers.add(localIdpExtendedMetadataProvider()); 
    providers.add(sfdcHttpExtendedMetadataProvider()); 
    return new CachingMetadataManager(providers); 
} 

// Filter automatically generates default SP metadata 
@Bean 
public MetadataGenerator metadataGenerator() { 
    MetadataGenerator metadataGenerator = new MetadataGenerator(); 
    metadataGenerator.setEntityId("com:revitas:saml:sp"); 
    metadataGenerator.setExtendedMetadata(extendedMetadata()); 
    metadataGenerator.setIncludeDiscoveryExtension(false); 
    metadataGenerator.setKeyManager(keyManager()); 
    return metadataGenerator; 
} 

// The filter is waiting for connections on URL suffixed with filterSuffix 
// and presents SP metadata there 
@Bean 
public MetadataDisplayFilter metadataDisplayFilter() { 
    return new MetadataDisplayFilter(); 
} 

// Handler deciding where to redirect user after successful login 
@Bean 
public SAMLSuccessRedirectHandler successRedirectHandler() { 
    SAMLSuccessRedirectHandler successRedirectHandler = 
      new SAMLSuccessRedirectHandler(); 
    return successRedirectHandler; 
} 

// Handler deciding where to redirect user after failed login 
@Bean 
public SimpleUrlAuthenticationFailureHandler authenticationFailureHandler() { 
    SimpleUrlAuthenticationFailureHandler failureHandler = 
      new SimpleUrlAuthenticationFailureHandler(); 
    failureHandler.setUseForward(true); 
    failureHandler.setDefaultFailureUrl("/error"); 
    return failureHandler; 
} 

@Bean 
public SAMLWebSSOHoKProcessingFilter samlWebSSOHoKProcessingFilter() throws Exception { 
    SAMLWebSSOHoKProcessingFilter samlWebSSOHoKProcessingFilter = new SAMLWebSSOHoKProcessingFilter(); 
    samlWebSSOHoKProcessingFilter.setAuthenticationSuccessHandler(successRedirectHandler()); 
    samlWebSSOHoKProcessingFilter.setAuthenticationManager(authenticationUtilService.getAuthenticationManager()); 
    samlWebSSOHoKProcessingFilter.setAuthenticationFailureHandler(authenticationFailureHandler()); 
    return samlWebSSOHoKProcessingFilter; 
} 

// Processing filter for WebSSO profile messages 
@Bean 
public SAMLProcessingFilter samlWebSSOProcessingFilter() throws Exception { 
    SAMLProcessingFilter samlWebSSOProcessingFilter = new SAMLProcessingFilter(); 
    samlWebSSOProcessingFilter.setAuthenticationManager(authenticationUtilService.getAuthenticationManager()); 
    samlWebSSOProcessingFilter.setAuthenticationSuccessHandler(successRedirectHandler()); 
    samlWebSSOProcessingFilter.setAuthenticationFailureHandler(authenticationFailureHandler()); 
    return samlWebSSOProcessingFilter; 
} 

@Bean 
public MetadataGeneratorFilter metadataGeneratorFilter() { 
    return new MetadataGeneratorFilter(metadataGenerator()); 
} 

// Handler for successful logout 
@Bean 
public SimpleUrlLogoutSuccessHandler successLogoutHandler() { 
    SimpleUrlLogoutSuccessHandler successLogoutHandler = new SimpleUrlLogoutSuccessHandler(); 
    successLogoutHandler.setDefaultTargetUrl("/"); 
    return successLogoutHandler; 
} 

// Logout handler terminating local session 
@Bean 
public SecurityContextLogoutHandler logoutHandler() { 
    SecurityContextLogoutHandler logoutHandler = 
      new SecurityContextLogoutHandler(); 
    logoutHandler.setInvalidateHttpSession(true); 
    logoutHandler.setClearAuthentication(true); 
    return logoutHandler; 
} 

// Filter processing incoming logout messages 
// First argument determines URL user will be redirected to after successful 
// global logout 
@Bean 
public SAMLLogoutProcessingFilter samlLogoutProcessingFilter() { 
    return new SAMLLogoutProcessingFilter(successLogoutHandler(), 
      logoutHandler()); 
} 

// Overrides default logout processing filter with the one processing SAML 
// messages 
@Bean 
public SAMLLogoutFilter samlLogoutFilter() { 
    return new SAMLLogoutFilter(successLogoutHandler(), 
      new LogoutHandler[]{logoutHandler()}, 
      new LogoutHandler[]{logoutHandler()}); 
} 

// Bindings 
private ArtifactResolutionProfile artifactResolutionProfile() { 
    final ArtifactResolutionProfileImpl artifactResolutionProfile = 
      new ArtifactResolutionProfileImpl(httpClient()); 
    artifactResolutionProfile.setProcessor(new SAMLProcessorImpl(soapBinding())); 
    return artifactResolutionProfile; 
} 

@Bean 
public HTTPArtifactBinding artifactBinding(ParserPool parserPool, VelocityEngine velocityEngine) { 
    return new HTTPArtifactBinding(parserPool, velocityEngine, artifactResolutionProfile()); 
} 

@Bean 
public HTTPSOAP11Binding soapBinding() { 
    return new HTTPSOAP11Binding(parserPool()); 
} 

@Bean 
public HTTPPostBinding httpPostBinding() { 
    return new HTTPPostBinding(parserPool(), velocityEngine()); 
} 

@Bean 
public HTTPRedirectDeflateBinding httpRedirectDeflateBinding() { 
    return new HTTPRedirectDeflateBinding(parserPool()); 
} 

@Bean 
public HTTPSOAP11Binding httpSOAP11Binding() { 
    return new HTTPSOAP11Binding(parserPool()); 
} 

@Bean 
public HTTPPAOS11Binding httpPAOS11Binding() { 
    return new HTTPPAOS11Binding(parserPool()); 
} 

// Processor 
@Bean 
public SAMLProcessorImpl processor() { 
    Collection<SAMLBinding> bindings = new ArrayList<SAMLBinding>(); 
    bindings.add(httpRedirectDeflateBinding()); 
    bindings.add(httpPostBinding()); 
    bindings.add(artifactBinding(parserPool(), velocityEngine())); 
    bindings.add(httpSOAP11Binding()); 
    bindings.add(httpPAOS11Binding()); 
    return new SAMLProcessorImpl(bindings); 
} 

/** 
* Define the security filter chain in order to support SSO Auth by using SAML 2.0 
* 
* @return Filter chain proxy 
* @throws Exception 
*/ 
@Bean 
public FilterChainProxy samlFilter() throws Exception { 
    List<SecurityFilterChain> chains = new ArrayList<SecurityFilterChain>(); 
    chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/login/**"), 
      samlEntryPoint())); 
    chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/logout/**"), 
      samlLogoutFilter())); 
    chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/metadata/**"), 
      metadataDisplayFilter())); 
    chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/SSO/**"), 
      samlWebSSOProcessingFilter())); 
    chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/SSOHoK/**"), 
      samlWebSSOHoKProcessingFilter())); 
    chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/SingleLogout/**"), 
      samlLogoutProcessingFilter())); 
    chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/discovery/**"), 
      samlIDPDiscovery())); 
    return new FilterChainProxy(chains); 
} 

我們試圖從鏈接「Spring Security SAML + HTTPS to another page」的建議,該建議1)禁用主機名驗證或2)註釋掉豆「TLSProtocolConfigurer」和進口的Salesforce證書到JDK cacerts的,但他們沒有工作,得到了相同的錯誤信息。

我們還可以嘗試其他方法嗎?

回答

0

1)設置MetadataTrustCheck爲假(extendedMetadataDelegate.setMetadataTrustCheck(假);每次添加的IdP的元數據時間(IdP進行簽名不是在這種情況下驗證)和

2)刪除tlsProtocolConfigurer的豆

應該可以解決你的問題。