2014-01-10 54 views
1

我使用Jersey 2作爲客戶端使用TLS訪問Web服務。我想選擇TLS使用的密碼,但我不知道如何。我的代碼:如何使用ApacheConnector選擇Jersey 2中的密碼套件?

ClientConfig clientConfig = new ClientConfig(); 
clientConfig.connectorProvider(new ApacheConnectorProvider()); 
SslConfigurator sslConfig = SslConfigurator.newInstance() 
    .trustStoreFile("truststore.jks") 
    .trustStorePassword("asdfgh") 
    .keyStoreFile("keystore.jks") 
    .keyPassword("asdfgh") 
    .securityProtocol("TLS"); // there is no method to select cipher suites for SslConfigurator 
clientConfig.property(ApacheClientProperties.SSL_CONFIG, sslContext); 

Client client = ClientBuilder.newBuilder() 
    .withConfig(clientConfig) 
    .build(); 

回答

1

我找到了解決辦法:

HttpClientConnectionManager connectionManager = createConnectionManager(clientConfig, sslContext, getHostnameVerifier(), true); 
clientConfig.property(ApacheClientProperties.CONNECTION_MANAGER, connectionManager); 

我粗略地複製從ApacheConnector下面的方法來創建的ConnectionManager:

private HttpClientConnectionManager createConnectionManager(
     final Configuration config, 
     SSLContext sslContext, 
     X509HostnameVerifier hostnameVerifier, 
     boolean useSystemProperties) { 

    final String[] supportedProtocols = useSystemProperties ? StringUtils.split(
      System.getProperty("https.protocols")) : null; 
    final String[] supportedCipherSuites = useSystemProperties ? StringUtils.split(
      System.getProperty("https.cipherSuites")) : null; 

    if (hostnameVerifier == null) { 
     hostnameVerifier = SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER; 
    } 

    LayeredConnectionSocketFactory sslSocketFactory; 
    if (sslContext != null) { 
     sslSocketFactory = new SSLConnectionSocketFactory(
       sslContext, supportedProtocols, supportedCipherSuites, hostnameVerifier); 
    } else { 
     if (useSystemProperties) { 
      sslSocketFactory = new SSLConnectionSocketFactory(
        (SSLSocketFactory) SSLSocketFactory.getDefault(), 
        supportedProtocols, supportedCipherSuites, hostnameVerifier); 
     } else { 
      sslSocketFactory = new SSLConnectionSocketFactory(
        SSLContexts.createDefault(), 
        hostnameVerifier); 
     } 
    } 

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

    final PoolingHttpClientConnectionManager connectionManager = 
      new PoolingHttpClientConnectionManager(registry); 

    if (useSystemProperties) { 
     String s = System.getProperty("http.keepAlive", "true"); 
     if ("true".equalsIgnoreCase(s)) { 
      s = System.getProperty("http.maxConnections", "5"); 
      final int max = Integer.parseInt(s); 
      connectionManager.setDefaultMaxPerRoute(max); 
      connectionManager.setMaxTotal(2 * max); 
     } 
    } 

    return connectionManager; 
}