SAML Java Sping Boot - Ошибка построения пути PKIX для ненадежных учетных данных - PullRequest
0 голосов
/ 28 мая 2020

Возникла эта проблема с настройкой SAML 2.0 в Java Spring Boot с использованием последних библиотек.

Я следовал этому руководству: https://www.programcreek.com/java-api-examples/?code=choonchernlim%2Fspring-security-adfs-saml2%2Fspring-security-adfs-saml2-master

Вот некоторые важные код, но дайте мне знать, поможет ли что-нибудь еще:

    @Bean
    public KeyManager keyManager()
    {
        return new JKSKeyManager(keyStoreResource, keystorePassword, ImmutableMap.of(keystoreKeyAlias, keystorePrivateKeyPassword), keystoreKeyAlias);
    }

    @Bean
    public SAMLDiscovery samlIDPDiscovery()
    {
        return new SAMLDiscovery();
    }

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

    @Bean
    public TLSProtocolConfigurer tlsProtocolConfigurer()
    {
        TLSProtocolConfigurer t = new TLSProtocolConfigurer();
        //t.setSslHostnameVerification("allowAll");
        return t;
    }

    // Configure TLSProtocolConfigurer
    @Bean
    public ProtocolSocketFactory protocolSocketFactory()
    {
        //return new TLSProtocolSocketFactory(keyManager(), null, "defaultAndLocalhost");
        return new TLSProtocolSocketFactory(keyManager(), null, "default");
    }

    @Bean
    public Protocol protocol()
    {
        return new Protocol("https", protocolSocketFactory(), 443);
    }

    @Bean
    public MethodInvokingFactoryBean socketFactoryInitialization()
    {
        MethodInvokingFactoryBean methodInvokingFactoryBean = new MethodInvokingFactoryBean();
        methodInvokingFactoryBean.setTargetClass(Protocol.class);
        methodInvokingFactoryBean.setTargetMethod("registerProtocol");
        methodInvokingFactoryBean.setArguments(new Object[] { "https", protocol() });
        return methodInvokingFactoryBean;
    }

    @Bean
    public CachingMetadataManager metadata() throws MetadataProviderException
    {
        HTTPMetadataProvider httpMetadataProvider = new HTTPMetadataProvider(new Timer(true), httpClient(), idpUrl);
        httpMetadataProvider.setParserPool(parserPool());

        //ExtendedMetadata em = new ExtendedMetadata(); //Attempt to explicitly add cert alias to extended metadata
        //em.setAlias(keystoreCertAlias);
        //em.setSigningKey("*.product.company.com");

        ExtendedMetadataDelegate extendedMetadataDelegate = new ExtendedMetadataDelegate(httpMetadataProvider);//, em);

        extendedMetadataDelegate.setMetadataTrustCheck(false);

        return new CachingMetadataManager(ImmutableList.<MetadataProvider>of(extendedMetadataDelegate));
    }

Вот ошибка:

2020-05-27 17:02:27.552 ERROR 41402 --- [           main] o.s.s.s.t.MetadataCredentialResolver     : PKIX path construction failed for untrusted credential: [subjectName='CN=*.product.company.com,O=Company,L=Location,ST=state,C=US']: unable to find valid certification path to requested target
2020-05-27 17:02:27.556  INFO 41402 --- [           main] o.a.c.httpclient.HttpMethodDirector      : I/O exception (javax.net.ssl.SSLPeerUnverifiedException) caught when processing request: SSL peer failed hostname validation for name: null
2020-05-27 17:02:27.557  INFO 41402 --- [           main] o.a.c.httpclient.HttpMethodDirector      : Retrying request
...

javax.net.ssl.SSLPeerUnverifiedException: SSL peer failed hostname validation for name: null
    at org.opensaml.ws.soap.client.http.TLSProtocolSocketFactory.verifyHostname(TLSProtocolSocketFactory.java:233) ~[openws-1.5.4.jar:na]
    at org.opensaml.ws.soap.client.http.TLSProtocolSocketFactory.createSocket(TLSProtocolSocketFactory.java:186) ~[openws-1.5.4.jar:na]
    at org.springframework.security.saml.trust.httpclient.TLSProtocolSocketFactory.createSocket(TLSProtocolSocketFactory.java:97) ~[spring-security-saml2-core-1.0.10.RELEASE.jar:1.0.10.RELEASE]
    at org.apache.commons.httpclient.HttpConnection.open(HttpConnection.java:707) ~[commons-httpclient-3.1.jar:na]
    at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$HttpConnectionAdapter.open(MultiThreadedHttpConnectionManager.java:1361) ~[commons-httpclient-3.1.jar:na]
    at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:387) ~[commons-httpclient-3.1.jar:na]
    at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171) ~[commons-httpclient-3.1.jar:na]
    at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397) ~[commons-httpclient-3.1.jar:na]
    at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323) ~[commons-httpclient-3.1.jar:na]
    at org.opensaml.saml2.metadata.provider.HTTPMetadataProvider.fetchMetadata(HTTPMetadataProvider.java:250) ~[opensaml-2.6.4.jar:na]
    at org.opensaml.saml2.metadata.provider.AbstractReloadingMetadataProvider.refresh(AbstractReloadingMetadataProvider.java:255) [opensaml-2.6.4.jar:na]
    at org.opensaml.saml2.metadata.provider.AbstractReloadingMetadataProvider.doInitialization(AbstractReloadingMetadataProvider.java:236) [opensaml-2.6.4.jar:na]
    at org.opensaml.saml2.metadata.provider.AbstractMetadataProvider.initialize(AbstractMetadataProvider.java:407) [opensaml-2.6.4.jar:na]
    at org.springframework.security.saml.metadata.ExtendedMetadataDelegate.initialize(ExtendedMetadataDelegate.java:167) [spring-security-saml2-core-1.0.10.RELEASE.jar:1.0.10.RELEASE]
    at com.company.product.ProductApplication.main(ProductApplication.java:10) ~[classes/:na]

Создание хранилища ключей JKS (с прикрепленным ключом):

keytool -genkeypair \
 -v \
 -keystore product.jks \
 -storepass hidden \
 -alias product \
 -dname 'CN=localhost, OU=Company, O=Org, L=Loc, ST=State, C=US' \
 -keypass hidden \
 -keyalg RSA \
 -keysize 2048 \
 -sigalg SHA256withRSA

Я также включил сертификат: Не удалось установить доверие к подписи для записи метаданных SAML Сертификат, предоставленный моим IDP, содержится в моем хранилище ключей:

keytool -importcert \
  -file cert.pem \
  -keystore product.jks \
  -alias idp-server \
  -storepass hidden

Я пробовал уже все следующие билеты:

SSL-узел не прошел проверку имени хоста в Spring SAML Пытался добавить сертификат, включенный в пароли в KeyManager (я установил пароль сертификата как пароль хранилища ключей, так как сертификата нет)

Spring Security SAML + HTTPS на другую страницу Пробовал allowAll в TLSProtocolConfigurer.setSslHostnameVerification и defaultAndLocalhost в TLSProtocolSock Конструктор etFactory.

Spring Security SAML IdP Metadata Certificate and Signature Проверка доверия уже отключена: extendedMetadataDelegate.setMetadataTrustCheck (false);

Не удалось установить доверие подписи для Запись метаданных SAML Пытался установить псевдоним сертификата внутри ExtendedMetadata, прикрепленного к делегату:

ExtendedMetadata em = new ExtendedMetadata();
em.setAlias(keystoreCertAlias);
em.setSigningKey("*.product.company.com"); //This is obfuscated
ExtendedMetadataDelegate extendedMetadataDelegate = new ExtendedMetadataDelegate(httpMetadataProvider, em);

Я склоняюсь к тому, что я неправильно настраиваю хранилище ключей с сертификатом. Я попытался преобразовать PEM в crt и cer, чтобы посмотреть, будет ли это иметь значение, но этого не произошло. Я могу заверить вас, что это сертификат IDP, а не сертификат домена (к вашему сведению, это намеренно не использует cacerts, а содержит сертификат внутри хранилища ключей для использования HTTPS).

Любые идеи / помощь очень приветствуются! Спасибо.

1 Ответ

0 голосов
/ 30 мая 2020

Чтобы исправить это, я удалил bean-компонент tlsProtocolConfigurer и все связанные с ним bean-компоненты. Я не совсем уверен, почему образец включил это, поскольку он отлично работает с HTTPS (и localhost) без него.

Примечание. Я предполагаю, что на самом деле проблема заключалась в том, что tlsProtocolConfigurer не находил сертификат в хранилище ключей, но для моего приложения весь bean-компонент не нужен, поэтому это стало спорным вопросом.

...