java - 如何使用 spring-ws 客户端使用不同的 keystore 调用同一个 webservice

标签 java spring ssl https spring-ws

我有一些应用程序需要在同一个应用程序服务器上运行。每个应用程序都需要使用特定于该应用程序的证书通过相同的 Web 服务进行身份验证。 显然我可以将所有证书放在同一个 keystore 中,但我如何指定我必须使用哪一个? 对于我使用 Spring WebServiceTemplate 的调用,我想找到可以在 spring xml 配置文件中轻松配置的内容。

我正在尝试遵循这个: How can I have multiple SSL certificates for a Java server

整个概念很清楚,但我不明白如何将它与 Spring WebServiceTemplate 链接以及如何在调用中指定我必须使用哪个证书。

最佳答案

有一种更简单的方法,而不是使用手动设置 SSL 上下文并使用拦截器删除内容长度 header 的自定义 HTTP 客户端工厂 bean(如果你问我,那就是小 Hokie)。

Spring 有一个 HttpsUrlConnectionMessageSender,它会自动正确设置 SSLContext,并允许您通过 KeyStoreManager 和 TrustStoreManager 指定不同的 keystore 和信任库。这种方法使得从客户端进行相互 SSL 身份验证变得更加清晰。

public class MyWebServiceClient extends WebServiceGatewaySupport implements MyWebServicePortType {

@Configuration
public static class MyClientConfig {
    @Value("${myws.endpoint.url}")
    private String url;

    @Value("${myws.keystore}")
    private Resource keyStore;
    @Value("${myws.keystore.password}")
    private String keyStorePass;
    @Value("${myws.truststore}")
    private Resource trustStore;
    @Value("${myws.truststore.password}")
    private String trustStorePass;

    @Bean 
    public Jaxb2Marshaller myWebServiceClientMarshaller() {
        Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
        marshaller.setContextPath("com.myws.types");
        return marshaller;
    }

    @Bean
    public MyWebServiceClient myWebServiceClient() throws Exception {
        MyWebServiceClient client = new MyWebServiceClient();
        client.setDefaultUri(this.url);
        client.setMarshaller(myWebServiceClientMarshaller());
        client.setUnmarshaller(myWebServiceClientMarshaller());

        KeyStore ks = KeyStore.getInstance("JKS");
        ks.load(keyStore.getInputStream(), keyStorePass.toCharArray());
        logger.info("Loaded keyStore: "+keyStore.getURI().toString());
        try { keyStore.getInputStream().close(); } catch(IOException e) {}
        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        keyManagerFactory.init(ks, keyStorePass.toCharArray());

        KeyStore ts = KeyStore.getInstance("JKS");
        ts.load(trustStore.getInputStream(), trustStorePass.toCharArray());
        logger.info("Loaded trustStore: "+trustStore.getURI().toString());
        try { trustStore.getInputStream().close(); } catch(IOException e) {}
        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        trustManagerFactory.init(ts);

        HttpsUrlConnectionMessageSender msgSender = new HttpsUrlConnectionMessageSender();
        msgSender.setKeyManagers(keyManagerFactory.getKeyManagers());
        msgSender.setTrustManagers(trustManagerFactory.getTrustManagers());

        client.setMessageSender(msgSender);

        return client;
    }


    // client port method implementations ...
    public MyOperationResponse processMyOperation(MyOperationRequest request) {
        return (MyOperationResponse) getWebServiceTemplate().marshalSendAndReceive(request, new SoapActionCallback("urn:ProcessMyOperation"));
    }

}

关于java - 如何使用 spring-ws 客户端使用不同的 keystore 调用同一个 webservice,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28169775/

相关文章:

java - 如何在 java 中从一个函数访问变量到另一个函数?该局部变量可以在函数中设为静态吗?

Java Arraylist 按引用还是按值工作?

java - 关于 javax.persistence JAR 的 Maven 依赖项?

macos - 使用 openssl 终端命令调试 SSL 连接

java - AsyncTask doInBackground() 方法中的空指针异常

java - hibernate 中没有外键的一对多

java - Spring 与 Hibernate 基于注解

spring - 是否可以使用gradle构建vaadin 14 Spring项目?

ruby-on-rails - 在安全 (https) 上运行 rails 并重定向非安全 (http) 请求以通过 webricks 确保安全

c# - 服务为什么有时会出现 SSL/TLS 错误