Spring-boot: принять любой сертификат - PullRequest
0 голосов
/ 17 января 2020

Я разработал приложение на основе микросервисов. У меня есть некоторые проблемы при интеграции 3 из них. Первый сервис - это приложение Spring-boot, которое подключено ко второму сервису, отвечающему за управление аутентификацией пользователя, которым является Keycloak. Наконец, доступ к этим службам управляется службой обратного прокси, здесь Nginx, отвечающей за безопасность связи с клиентами, как показано здесь: micro-services architecture

Прежде всего клиент получает токен от keycloak, который работает нормально. Затем клиент использует этот токен для доступа к сервисам из Spring, что не удается. Приложение Spring настроено так:

keycloak.realm=my-realm
keycloak.auth-server-url=https://172.17.0.1/auth
keycloak.ssl-required=external
keycloak.bearer-only=true
keycloak.resource=my-resource
keycloak.credentials.secret=my-secret

IP-адрес сервера авторизации - это IP Docker. Когда я пытаюсь получить доступ к сервису отдыха, я получаю эту ошибку:

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

Я пытался деактивировать проверку сертификации с помощью этого кода (kotlin) в моем приложении Spring:

val sslContext = SSLContext.getInstance("SSL")
sslContext.init(null, arrayOf<TrustManager>(ECollabTrustManager()), SecureRandom())
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.socketFactory)
HttpsURLConnection.setDefaultHostnameVerifier(NoopHostnameVerifier())

А вот код TrustManager:

class ECollabTrustManager : X509TrustManager {
    override fun checkClientTrusted(certs: Array<out X509Certificate>?, authType: String?) {
    }

    override fun checkServerTrusted(certs: Array<out X509Certificate>?, authType: String?) {
    }

    override fun getAcceptedIssuers(): Array<X509Certificate>? {
        return null
    }

}

Но это не устраняет ошибку. Есть идеи ? Заранее благодарим за помощь.

1 Ответ

0 голосов
/ 17 января 2020

Похоже, что вы уже используете HostnameVerifier, который принимает все хосты как действительные (то есть NoopHostnameVerifier), поэтому осталось только создать и использовать TrustManager, который доверяет всем сертификатам (простой Java следует) :

TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager()
{
   @Override
   public X509Certificate[] getAcceptedIssuers()
   {
      return null;
   }

   @Override
   public void checkServerTrusted(X509Certificate[] chain, String authType)
            throws CertificateException
   {
   }

   @Override
   public void checkClientTrusted(X509Certificate[] chain, String authType)
            throws CertificateException
   {

   }
} };

SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
...