当前位置: 首页 > 知识库问答 >
问题:

javax.net.ssl.SSLPeerUnverifiedException: SSL peer 未能通过名称的主机名验证: null

闾丘文昌
2023-03-14

我们使用Spring SAML扩展将Salesforce设置为IDP,我们的应用程序是SP。但我们得到错误“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链接到另一个页面”的建议,其中1)禁用主机名验证,或2)注释掉Bean“TLSProtocolConfigurer”,并将Salesforce证书导入JDK cacerts,但它们都不起作用,并收到相同的错误消息。

我们还可以尝试什么方法?

共有1个答案

柴凌
2023-03-14

1) 将MetadataTrustCheck设置为false(extendedMetadataDelegate.SetMetadataTrust检查(false);每次添加IdP的元数据时(本例中未验证IdP签名),以及

2) 删除tlsProtocolConfigurer Bean

应该解决你的问题。

 类似资料:
  • 问题内容: 我正在开发一个Android应用,并且需要访问一个HTTPS地址。我正在使用Volley来请求我的数据,但现在却收到此错误 要获得SSL工厂,我需要这样做: 队列初始化: 这是堆栈跟踪: 我搜索了错误,但没有找到适合我的情况的内容。谁能帮我? 问题答案: 让我们假设你的服务器的应用程序是具有服务器证书中的服务器机内托管的,例如。然后,在验证方法内部,您可以验证。 您可以通过以下链接阅读

  • 我正在esp32上实现一个websocket服务器,并且在android studio Simulator上运行的应用程序上使用okhttp lib。 我正在使用由openssl命令生成的自分配证书:openssl req-newkey rsa:2048-nodes-keyout prvtkey.pem-x509-days 3650-out cacert.pem-subj“/cn=esp32 HT

  • 在测试我的客户机-服务器分布式系统时,我最初惊讶地得知TLS的默认JSSE实现不进行主机名验证。我在这个问题中尝试了公认的答案,但我的用例有点不同。我使用RabbitMQ的连接工厂,它抽象了SSLSocket的构造。我只是为连接工厂提供了一个SSLContext。我确实找到了很多关于HTTPS的信息,甚至还有一些其他协议,但并不是总能使用的通用协议,即使是自定义协议。 但是,除了使用之外,关于创建

  • 问题内容: 跟进正则表达式以匹配主机名或IP地址? 并使用对有效主机名的限制作为参考,在Python中匹配/验证主机名/ fqdn(完全限定域名)的最易读,简洁的方法是什么?我在下面的尝试中已经回答过,欢迎改进。 问题答案: import re def is_valid_hostname(hostname): if len(hostname) > 255: return False if host

  • 我在令牌使用者上得到以下错误。任何帮助解决这将是非常感谢的。多谢了。 “IDX10503:签名验证失败。 公共无效配置(IApplicationBuilder应用程序)

  • 我已经在我的android应用程序中添加了Firebase手机认证,它运行良好,但是应用程序名称没有包含在短信验证消息中,因为它出现在Firebase控制台的短信模板中:(%LOGIN_CODE%是%APP_NAME%的校验码。)。 我收到的消息如下:(%LOGIN_CODE%是您的验证码) 我的应用程序的调试版本和发布版本都有这个问题。 那么,如何将应用程序名称添加到此消息中。