Spring saml 与 IDP 服务器的集成使名称的 SSL 对等点主机名验证失败:null

Posted

技术标签:

【中文标题】Spring saml 与 IDP 服务器的集成使名称的 SSL 对等点主机名验证失败:null【英文标题】:Spring saml integration with IDP server got SSL peer failed hostname validation for name: null 【发布时间】:2017-11-23 18:26:39 【问题描述】:

作为服务商,我正在使用spring saml与第三方IDP服务器集成。

我们插入了 2 个 X.509 证书,一个用于签名,另一个用于加密,还有一个来自 IDP 的 SSL 证书作为 java 密钥库中的公钥。

环境: Java 版本: 1.7 春季版: 4.3.7.RELEASE Spring Security 版本: 4.2.2.RELEASE spring-security-saml2-core: 1.0.2.RELEASE

错误说明: 用户从 IDP 服务器认证后,IDP 服务器将该用户重定向到我们的 SP,并将工件发回。当我们尝试将 artifactResolve 发送回 IDP 服务器时发生错误。

错误:SSL peer failed hostname validation for name: null

以下是spring安全配置的代码sn-p和错误日志。

Spring 安全配置

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter

    @Autowired
    private SAMLUserDetailsServiceImpl samlUserDetailsServiceImpl;

    // 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() 
        return new WebSSOProfileConsumerImpl();
    

    // 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() 
        return new SingleLogoutProfileImpl();
    

    @Bean
    public KeyManager keyManager() 
        DefaultResourceLoader loader = new DefaultResourceLoader();
        Resource storeFile = loader.getResource("classpath:/saml/project.jks");
        String storePass = "password";  
        Map<String, String> passwords = new HashMap<String, String>();

        passwords.put("project", "password");
        passwords.put("project.sign", "password");
        // passwords.put("project.ssl", "password");
        String defaultKey = "project";


        return new JKSKeyManager(storeFile, storePass, passwords, defaultKey);
    



    // Setup TLS Socket Factory
    @Bean
    public TLSProtocolConfigurer tlsProtocolConfigurer() 
        return new 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.setLocal(true);
        extendedMetadata.setAlias("project");
        extendedMetadata.setSecurityProfile("metaiop");
        extendedMetadata.setSslSecurityProfile("metaiop");

        extendedMetadata.setSigningKey("project.sign");
        extendedMetadata.setEncryptionKey("project");
        extendedMetadata.setTlsKey("project.ssl");

        extendedMetadata.setRequireArtifactResolveSigned(false);
        extendedMetadata.setRequireLogoutRequestSigned(false);
        extendedMetadata.setRequireLogoutResponseSigned(false);
        //Turn off Idp discovery
        extendedMetadata.setIdpDiscoveryEnabled(false);
        return extendedMetadata;
    

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


    @Bean
    public FilesystemMetadataProvider IdpFilesystemMetadataProvider()
            throws MetadataProviderException 
        ClassLoader classLoader = getClass().getClassLoader();
        FilesystemMetadataProvider filesystemMetadataProvider = new FilesystemMetadataProvider(new File(classLoader.getResource("metadata/idp.xml").getFile()));
        filesystemMetadataProvider.setParserPool(parserPool());

        return filesystemMetadataProvider;
    

    // IDP Metadata configuration
        @Bean
        public ExtendedMetadataDelegate IdpExtendedMetadataProvider()
                throws MetadataProviderException 
            ExtendedMetadataDelegate extendedMetadataDelegate = 
                    new ExtendedMetadataDelegate(IdpFilesystemMetadataProvider());
            extendedMetadataDelegate.setMetadataTrustCheck(false);
            extendedMetadataDelegate.setMetadataRequireSignature(false);
            return extendedMetadataDelegate;
        

    @Bean
    public FilesystemMetadataProvider SpFilesystemMetadataProvider()
            throws MetadataProviderException 
        ClassLoader classLoader = getClass().getClassLoader();
        FilesystemMetadataProvider filesystemMetadataProvider = new FilesystemMetadataProvider(new File(classLoader.getResource("metadata/sp_stg.xml").getFile()));
        filesystemMetadataProvider.setParserPool(parserPool());
        return filesystemMetadataProvider;
    


    // SP Metadata configuration
    @Bean
    public ExtendedMetadataDelegate SPExtendedMetadataProvider()
            throws MetadataProviderException 
        ExtendedMetadataDelegate extendedMetadataDelegate = 
                new ExtendedMetadataDelegate(SpFilesystemMetadataProvider(), extendedMetadata());
        // extendedMetadataDelegate.setMetadataTrustCheck(true);
        // 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(IdpExtendedMetadataProvider());
        providers.add(SPExtendedMetadataProvider());
        CachingMetadataManager cachingMetadataManager = new CachingMetadataManager(providers);
        cachingMetadataManager.setHostedSPName("http://SPdomain/projectstg");
        cachingMetadataManager.setDefaultIDP("https://IDPdomain/FIM/IDPFed/saml20");
        return cachingMetadataManager;
    

    @Bean
    public MetadataDisplayFilter metadataDisplayFilter() 
        return new MetadataDisplayFilter();
    

    // Handler deciding where to redirect user after successful login
    @Bean
    public SavedRequestAwareAuthenticationSuccessHandler successRedirectHandler() 
        SavedRequestAwareAuthenticationSuccessHandler successRedirectHandler =
                new SavedRequestAwareAuthenticationSuccessHandler();
        successRedirectHandler.setDefaultTargetUrl("/landing");
        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(authenticationManager());
        samlWebSSOHoKProcessingFilter.setAuthenticationFailureHandler(authenticationFailureHandler());
        return samlWebSSOHoKProcessingFilter;
    

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

    // 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()));
        List<MetadataProvider> providers = new ArrayList<MetadataProvider>();
        MetadataManager metadataManager = null;
        try 
            providers.add(IdpExtendedMetadataProvider());
            metadataManager = new MetadataManager(providers);
         catch (Exception e) 
            // TODO: handle exception
        
        artifactResolutionProfile.setMetadata(metadataManager);
        metadataManager.refreshMetadata();
        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);
    

    /**
     * Returns the authentication manager currently used by Spring.
     * It represents a bean definition with the aim allow wiring from
     * other classes performing the Inversion of Control (IoC).
     * 
     * @throws  Exception 
     */
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception 
        return super.authenticationManagerBean();
    

    /**
     * Defines the web based security configuration.
     * 
     * @param   http It allows configuring web based security for specific http requests.
     * @throws  Exception 
     */
    @Override  
    protected void configure(HttpSecurity http) throws Exception 
        http
            .httpBasic()
                .authenticationEntryPoint(samlEntryPoint());
        http
            .csrf()
                .disable();
        http
            // .addFilterBefore(metadataGeneratorFilter(), ChannelProcessingFilter.class)
            .addFilterAfter(samlFilter(), BasicAuthenticationFilter.class);
        http        
            .authorizeRequests()
            .antMatchers("/").permitAll()
            .antMatchers("/error").permitAll()
            .antMatchers("/saml/**").permitAll()
            .requestMatchers(new AntPathRequestMatcher("/test")).authenticated();
        http
            .logout()
                .logoutSuccessUrl("/");
    

    /**
     * Sets a custom authentication provider.
     * 
     * @param   auth SecurityBuilder used to create an AuthenticationManager.
     * @throws  Exception 
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception 
        auth
            .authenticationProvider(samlAuthenticationProvider());
    

    @Override
    public void configure(WebSecurity web) throws Exception 
        web
            .ignoring()
            .antMatchers(
                    "/css/**",
                    "/fonts/**",
                    "/image/**",
                    "/js/**",
                    "/dist/**");
    


错误日志:

2017-06-21|10:17 42,975|http-nio-8080-exec-6|HttpConnection.java|DEBUG|Open connection to idpDomain:443
2017-06-21|10:17 42,990|http-nio-8080-exec-6|HttpMethodDirector.java|DEBUG|Closing the connection.
2017-06-21|10:17 42,990|http-nio-8080-exec-6|HttpMethodDirector.java|DEBUG|Method retry handler returned false. Automatic recovery will not be attempted
2017-06-21|10:17 42,990|http-nio-8080-exec-6|HttpConnection.java|DEBUG|Releasing connection back to connection manager.
2017-06-21|10:17 42,990|http-nio-8080-exec-6|MultiThreadedHttpConnectionManager.java|DEBUG|Freeing connection, hostConfig=HostConfiguration[host=https://idpDomain]
2017-06-21|10:17 42,990|http-nio-8080-exec-6|IdleConnectionHandler.java|DEBUG|Adding connection at: 1498011462990
2017-06-21|10:17 42,991|http-nio-8080-exec-6|MultiThreadedHttpConnectionManager.java|DEBUG|Notifying no-one, there are no waiting threads
2017-06-21|10:17 42,991|http-nio-8080-exec-6|AbstractAuthenticationProcessingFilter.java|DEBUG|Authentication request failed: org.springframework.security.authentication.AuthenticationServiceException: Error de
coding incoming SAML message
org.springframework.security.authentication.AuthenticationServiceException: Error decoding incoming SAML message
        at org.springframework.security.saml.SAMLProcessingFilter.attemptAuthentication(SAMLProcessingFilter.java:97)
        at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214)
        at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:185)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal(BasicAuthenticationFilter.java:158)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214)
        at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
        at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
        at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
        at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:528)
        at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1099)
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:670)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:745)
Caused by: org.opensaml.ws.message.decoder.MessageDecodingException: Could not decode artifact response message
        at org.springframework.security.saml.websso.ArtifactResolutionProfileBase.resolveArtifact(ArtifactResolutionProfileBase.java:126)
        at org.opensaml.saml2.binding.decoding.HTTPArtifactDecoderImpl.doDecode(HTTPArtifactDecoderImpl.java:94)
        at org.opensaml.ws.message.decoder.BaseMessageDecoder.decode(BaseMessageDecoder.java:79)
        at org.opensaml.saml2.binding.decoding.BaseSAML2MessageDecoder.decode(BaseSAML2MessageDecoder.java:70)
        at org.springframework.security.saml.processor.SAMLProcessorImpl.retrieveMessage(SAMLProcessorImpl.java:105)
        at org.springframework.security.saml.processor.SAMLProcessorImpl.retrieveMessage(SAMLProcessorImpl.java:172)
        at org.springframework.security.saml.SAMLProcessingFilter.attemptAuthentication(SAMLProcessingFilter.java:80)
        ... 40 more
Caused by: org.opensaml.ws.message.decoder.MessageDecodingException: Error when sending request to artifact resolution service.
        at org.springframework.security.saml.websso.ArtifactResolutionProfileImpl.getArtifactResponse(ArtifactResolutionProfileImpl.java:110)
        at org.springframework.security.saml.websso.ArtifactResolutionProfileBase.resolveArtifact(ArtifactResolutionProfileBase.java:101)
        ... 46 more
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:186)
        at org.apache.commons.httpclient.HttpConnection.open(HttpConnection.java:707)
        at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$HttpConnectionAdapter.open(MultiThreadedHttpConnectionManager.java:1361)
        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:346)
        at org.springframework.security.saml.websso.ArtifactResolutionProfileImpl.getArtifactResponse(ArtifactResolutionProfileImpl.java:99)
        ... 47 more

我们试过了

@Bean
    public TLSProtocolConfigurer tlsProtocolConfigurer() 
        TLSProtocolConfigurer tLSProtocolConfigurer = new TLSProtocolConfigurer();
        tLSProtocolConfigurer.setSslHostnameVerification("allowAll");
        return tLSProtocolConfigurer;
    

几乎所有关于这个错误的解决方案都在 *** 上,但它没有奏效。

@Vladimír Schäfer 我们需要您的建议,谢谢!!

【问题讨论】:

【参考方案1】:

您的 Idp 使用的 SSL 协议是什么,如果他们使用 TLSv1.2,则 JDK 版本需要升级到 JDK8,因为 JDK8 HTTPClient 默认使用 TLSv1.2,但 JDK7 使用 TLSv1

【讨论】:

以上是关于Spring saml 与 IDP 服务器的集成使名称的 SSL 对等点主机名验证失败:null的主要内容,如果未能解决你的问题,请参考以下文章

Spring SAML 与 WSO2 身份服务器集成,无法识别 SAML 消息

wso2 spring security saml 无状态集成

Springboot 使用 SAML 与 IDP 集成,并提供 .pem 文件

是否有用于将 SAML 与 Spring Boot 应用程序集成的 Spring Boot SAML 客户端?

如何在运行时在 spring-SAML 中添加新的 idp 元数据

Spring security Saml - SP 和 IDP 的时间差