2015-10-23 91 views
1

我正在Java 1.8上編寫一個使用Spring Boot v 1.2.7.RELEASE的服務器。我的代碼完全由註釋配置,目前除Maven pom外沒有任何XML。編寫Spring引導WSDL *客戶端*提供認證證書

我的Spring Boot服務器必須查詢WSDL服務器來驗證用戶身份。在這種情況下,我的服務器是WSDL服務的客戶端。我的應用程序需要向WS服務器提供證書來驗證自己並獲得訪問權限,然後進行查詢。所以,我有一個JKS與我的應用程序證書和一個服務器信任庫JKS。

此外,通過https完成與WS服務器的連接,但我認爲這是由WebServiceGatewaySupport處理的。

我發現許多WS客戶端的例子,以及在Spring Boot中配置SSL作爲服務器的許多例子,但都沒有展示如何使用SSL作爲客戶端。在我的研究中,我看到了一些暗示可以用一些註釋完成但沒有具體的頁面。

我在想這一定是可能的,任何幫助將不勝感激,謝謝!

回答

0

這裏是我有,使用Apache的HttpClient 4.5.2:

import java.io.IOException; 
import java.io.InputStream; 
import java.security.KeyManagementException; 
import java.security.KeyStore; 
import java.security.KeyStoreException; 
import java.security.NoSuchAlgorithmException; 
import java.security.UnrecoverableKeyException; 
import java.security.cert.CertificateException; 
import java.util.Arrays; 
import java.util.List; 

import javax.net.ssl.SSLContext; 

import org.apache.http.Header; 
import org.apache.http.HttpHeaders; 
import org.apache.http.HttpHost; 
import org.apache.http.auth.AuthScope; 
import org.apache.http.auth.Credentials; 
import org.apache.http.auth.UsernamePasswordCredentials; 
import org.apache.http.client.CredentialsProvider; 
import org.apache.http.conn.socket.LayeredConnectionSocketFactory; 
import org.apache.http.conn.ssl.DefaultHostnameVerifier; 
import org.apache.http.conn.ssl.SSLConnectionSocketFactory; 
import org.apache.http.impl.client.BasicCredentialsProvider; 
import org.apache.http.impl.client.CloseableHttpClient; 
import org.apache.http.impl.client.HttpClientBuilder; 
import org.apache.http.message.BasicHeader; 
import org.apache.http.ssl.SSLContexts; 
import org.springframework.beans.factory.annotation.Value; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.core.io.Resource; 
import org.springframework.oxm.jaxb.Jaxb2Marshaller; 
import org.springframework.ws.WebServiceMessageFactory; 
import org.springframework.ws.pox.dom.DomPoxMessageFactory; 
import org.springframework.ws.transport.WebServiceMessageSender; 
import org.springframework.ws.transport.http.HttpComponentsMessageSender; 
import org.springframework.ws.transport.http.MessageDispatcherServlet; 

@Configuration 
class ApplicationIntegrationTestConfiguration { 
    @Value("${lcm.request.endpoint}") 
    private String endpointUri; 
    @Value("${lcm.request.keystorepath}") 
    private Resource keyStore; 
    @Value("${lcm.request.keystorepass}") 
    private char[] keyStorePass; 
    @Value("${lcm.request.keystoretype}") 
    private String keyStoreType; 
    @Value("${lcm.request.truststorepath}") 
    private Resource trustStore; 
    @Value("${lcm.request.truststorepass}") 
    private char[] trustStorePass; 
    @Value("${lcm.request.truststoretype}") 
    private String trustStoreType; 

    private static final String ACCEPT_HEADER_VALUE = "application/xml"; 
    @Bean 
    public WebServiceMessageSender messageSender(
      LayeredConnectionSocketFactory factory) throws Exception { 
     Header header = new BasicHeader(HttpHeaders.ACCEPT, ACCEPT_HEADER_VALUE); 
     List<Header> defaultHeaders = Arrays.asList(header); 
     CloseableHttpClient client = HttpClientBuilder.create() 
      .setSSLSocketFactory(factory) 
      .setDefaultHeaders(defaultHeaders) 
      .build(); 

     HttpComponentsMessageSender messageSender = new HttpComponentsMessageSender(
       client); 

     // needed if used as a standalone client 
     //messageSender.afterPropertiesSet(); 
     return messageSender; 
    } 
    @Bean 
    public LayeredConnectionSocketFactory sslFactory() { 
     try { 
      final KeyStore keystore = KeyStore.getInstance(this.keyStoreType); 
      try (InputStream readStream = this.keyStore.getInputStream()) { 
       keystore.load(readStream, this.keyStorePass); 
      } 

      final KeyStore truststore = KeyStore.getInstance(this.trustStoreType); 
      try (InputStream readStream = this.trustStore.getInputStream()) { 
       truststore.load(readStream, this.trustStorePass); 
      } 

      SSLContext sslContext = SSLContexts 
        .custom() 
        .loadTrustMaterial(truststore, null) 
        .loadKeyMaterial(keystore, this.keyStorePass) 
        .build(); 
      SSLConnectionSocketFactory sslConnectionFactory = new SSLConnectionSocketFactory(sslContext, 
        new DefaultHostnameVerifier() 
        ); 
      return sslConnectionFactory; 
     } catch (KeyManagementException | UnrecoverableKeyException | 
       NoSuchAlgorithmException | KeyStoreException 
       | CertificateException | IOException e) { 
      throw new IllegalArgumentException(String.format("Problem with keystore %s or truststore %s", 
        this.keyStore, this.trustStore), e); 
     } 
    } 
    @Bean 
    public PingClient pingClient(Jaxb2Marshaller marshaller, 
      WebServiceMessageFactory messageFactory, WebServiceMessageSender messageSender) { 
     PingClient client = new PingClient(); 
     client.setDefaultUri(this.endpointUri + "/Ping/v1"); 
     client.setMarshaller(marshaller); 
     client.setUnmarshaller(marshaller); 
     client.setMessageFactory(messageFactory); 
     client.setMessageSender(messageSender); 
     return client; 
    } 

    // this bean is the key in selecting between SOAP and POX (plain old XML) 
    @Bean(name = MessageDispatcherServlet.DEFAULT_MESSAGE_FACTORY_BEAN_NAME) 
    public WebServiceMessageFactory messageFactory() { 
     return new DomPoxMessageFactory(); 
    } 

    @Bean 
    public Jaxb2Marshaller marshaller() { 
     Jaxb2Marshaller marshaller = new Jaxb2Marshaller(); 
     marshaller.setPackagesToScan("my.packages"); 
     return marshaller; 
    } 
} 

我也有一個示例項目做幾乎同樣的here,並通過添加使用基本身份驗證憑據here的相同。他們沒有安裝密鑰庫或信任庫(因爲它們很難獲得可發佈的版本),但他們應該提供幫助。

請注意,您不能使用.jks作爲客戶端證書,您必須轉換爲.jceks密鑰存儲格式。