2015-02-21 6 views
2

Я пытаюсь отправить вызов службы с использованием URL-адреса SSL. Я получаю исключение.ApacheConnectorProvider with Jersey for SSL throws Ошибка

javax.ws.rs.ProcessingException: 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 
    at org.glassfish.jersey.apache.connector.ApacheConnector.apply(ApacheConnector.java:517) 
    at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:246) 
    at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:667) 
    at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:664) 
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315). 

Я использую Spring, Джерси и пытается использовать ApacheClient (Причина использования О Weblogic оно принимает Weblogic конкретный обработчик HTTP, я знаю, мы можем использовать «DUseSunHttpHandler = истина», но я не хочу делать это на производстве).

Обратите внимание, что с реализацией только Джерси он работал с http на Tomcat и Weblogic. Но с HTTPS он работал в Tomcat не в Weblogic. Так что пошел на ApacheConnectionProvider, оттуда он тоже не работает в Tomcat.

запись POM

<dependency> 
     <groupId>org.glassfish.jersey.core</groupId> 
     <artifactId>jersey-client</artifactId> 
     <version>2.15</version> 
     <scope>compile</scope> 
    </dependency> 
    <dependency> 
     <groupId>org.glassfish.jersey.core</groupId> 
     <artifactId>jersey-common</artifactId> 
     <version>2.15</version> 
     <scope>compile</scope> 
    </dependency> 
    <dependency> 
     <groupId>javax.ws.rs</groupId> 
     <artifactId>javax.ws.rs-api</artifactId> 
     <version>2.0.1</version> 
     <scope>compile</scope> 
    </dependency> 
    <dependency> 
     <groupId>org.apache.httpcomponents</groupId> 
     <artifactId>httpclient</artifactId> 
     <version>4.4</version> 
    </dependency> 
    <dependency> 
     <groupId>org.glassfish.jersey.connectors</groupId> 
     <artifactId>jersey-apache-connector</artifactId> 
     <version>2.15</version> 
    </dependency> 

Код

public Client getClient() { 
     ClientConfig clientConfig = new ClientConfig(); 
     clientConfig.property(ApacheClientProperties.CONNECTION_MANAGER, new PoolingHttpClientConnectionManager()); 
     //config your ssl for apache connector 
     SslConfigurator sslConfig = SslConfigurator.newInstance(); 

     String trustStoreFile = "C:\\Development\\svn\\ecomm-webapp\\profiles\\uat\\workflowtrust.jks"; 
     String trustStorePassword ="ABC12"; 
     String keyStoreFile = "C:\\Development\\svn\\ecomm-webapp\\profiles\\uat\\workflow.jks"; 
     String keyPassword ="abc12"; 
     sslConfig.trustStoreFile(trustStoreFile).keyStoreFile(keyStoreFile).keyStorePassword(trustStorePassword).trustStorePassword(trustStorePassword).securityProtocol("SSL"); 
     clientConfig.property(ApacheClientProperties.SSL_CONFIG, sslConfig); 
     ApacheConnectorProvider connector = new ApacheConnectorProvider(); 
     clientConfig.connectorProvider(connector); 

     return ClientBuilder.newClient(clientConfig); 
    } 

телефонный код

public <T> T postXmlFile(final File inputXml, final String targetUrl, Class<T> resultResponse, final RestfulServiceVerifier<T> restfulServiceVerifier) throws FunctionalException { 
     return post(MediaType.APPLICATION_XML_TYPE, MediaType.TEXT_XML_TYPE, inputXml, targetUrl, resultResponse, restfulServiceVerifier); 
    } 

    private <T> T post(final MediaType type, final MediaType accept, final Object entity, final String targetUrl, Class<T> resultResponse, final RestfulServiceVerifier<T> restfulServiceVerifier) throws FunctionalException { 
     Response response = null; 
     int responseStatus = -1; 
     T result = null; 
     while (restfulServiceVerifier.hasNextWorkFlowHit()) { 
      try { 
       response = restFulWebTargetFactory.getClient().target(targetUrl) 
         .request(type) 
         .post(Entity.entity(entity, accept)); 

       responseStatus = response.getStatus(); 
       if(EcommConstants.WORKFLOW_ORDER_PROPOSAL_SUCCESS_CODE == responseStatus) { 
        final String resultInString = response.readEntity(String.class); 
        //for audit purpose 
        if (LOG_XML_MESSAGE) { 
         log.info("XML Response "+ resultInString); 
        } 
        result = unMarshalXML(resultInString, resultResponse); 
        restfulServiceVerifier.checkResponse(result, responseStatus); 
       } 

      } catch (WorkFlowRetryException workFlowException) { 
       throw new FunctionalException("WebService post failed. ", workFlowException); 
      }catch (WorkFlowValidationException workFlowValidationException) { 
       log.error("Service Response Validation Exception " + workFlowValidationException.getErrorCode() + " Error Description " + workFlowValidationException.getDescription(), workFlowValidationException); 
      }catch (final Exception e) { 
       log.error("Exception occurred" , e); 
      } finally { 
       if(null != response) { 
        response.close(); 
       } 
      } 
     } 
     if(-1 == responseStatus) { 
      throw new FunctionalException("WebService post failed. ", new Exception()); 
     } 
     return result; 
    } 

ответ

3

Я установил его, пожалуйста, найти Солу Тион. Я изменил метод getClient().

  1. Я создал org.apache.http.conn.ssl.DefaultHostnameVerifier. Вот фрагмент кода, я changed.DefaultHostnameVerifier (мне просто нужно по умолчанию один)
  2. настроенного SslConfigurator с Целевым магазином и Key профиль
  3. создавшего LayeredConnectionSocketFactory и вводил SSLContext из SslConfigurator и defaultHostnameVerifier
  4. Создано реестра для HTTP и HTTPS
  5. Создание ClientConfig для установки диспетчера соединений с PoolingHttpClientConnectionManager с закачиваемой реестра
  6. и установить SSL Config для Client Config
  7. Создан ApacheConnectorProvider и установите Clie ntConfig

Пример кода

private SslConfigurator createSSLContext() { 
     return SslConfigurator.newInstance() 
       .trustStoreFile(trustStoreFile) 
       .trustStorePassword(trustStorePassword) 
       .keyStoreFile(keyStoreFile) 
       .keyPassword(keyPassword).securityProtocol("SSL"); 
    } 


    @Override 
    public Client getClient() { 

     HostnameVerifier defaultHostnameVerifier=new DefaultHostnameVerifier(); 
     SslConfigurator sslConfig = createSSLContext(); 
     LayeredConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(
       sslConfig.createSSLContext(), 
       defaultHostnameVerifier); 

     final Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create() 
       .register("http", PlainConnectionSocketFactory.getSocketFactory()) 
       .register("https", sslSocketFactory) 
       .build(); 

     ClientConfig clientConfig = new ClientConfig(); 
     clientConfig.property(ApacheClientProperties.CONNECTION_MANAGER, new PoolingHttpClientConnectionManager(registry)); 

     clientConfig.property(ApacheClientProperties.SSL_CONFIG, sslConfig); 

     ApacheConnectorProvider connector = new ApacheConnectorProvider(); 
     clientConfig.connectorProvider(connector); 
     return ClientBuilder.newBuilder().withConfig(clientConfig).build(); 
    } 
+0

Использование джерси-клиента 2,21, я не 'ApacheClientProperties.SSL_CONFIG'. Но, похоже, достаточно предоставить 'SSLContext' для sslSocketFactory. – Hank

+0

Вы можете подключать соединения и делать запросы на одинаковые подключения – Labeo