【问题标题】:Using WebServiceTemplate with a keystore将 WebServiceTemplate 与密钥库一起使用
【发布时间】:2010-03-10 19:14:27
【问题描述】:

是否可以使用 java 密钥库配置 WebServiceTemplate?

编辑
我正在寻找一种在spring config中配置密钥库位置的方法

【问题讨论】:

    标签: java spring ssl spring-ws


    【解决方案1】:

    我在六年后发布这个答案,但老实说,没有一个帖子提供完整而简洁的解决方案。您只需要 spring-ws-core (2.1.4.RELEASE +) 和 spring-we-security (2.2.4.RELEASE +) 依赖项。下一步是将自定义 keystore 和 truststore 配置为 bean,然后在 spring 配置中将它们注入 Web 服务模板。

    <bean id="myKeyStore" class="org.springframework.ws.soap.security.support.KeyStoreFactoryBean">
    	<property name="location" value="file:/tmp/config/my-keystore.jks"/>
    	<property name="password" value="password"/>
    </bean>
    
    <bean id="myTrustStore" class="org.springframework.ws.soap.security.support.KeyStoreFactoryBean">
    	<property name="location" value="file:/tmp/config/my-truststore.jks"/>
    	<property name="password" value="different_password"/>
    </bean>
    
    <bean id="template" class="org.springframework.ws.client.core.WebServiceTemplate">
        <property name="messageSender">
            <bean class="org.springframework.ws.transport.http.HttpsUrlConnectionMessageSender">
                <property name="trustManagers">
    		<bean class="org.springframework.ws.soap.security.support.TrustManagersFactoryBean">
    			<property name="keyStore" ref="mytrustStore" />
    		</bean>
    	    </property>
    	    <property name="keyManagers">
    		<bean class="org.springframework.ws.soap.security.support.KeyManagersFactoryBean">
    			<property name="keyStore" ref="myKeyStore" />
    			<property name="password" value="password" />
    		</bean>
    	   </property>
            </bean>
        </property>
    </bean>

    总之不用写代码,用spring config就可以轻松实现用例。

    【讨论】:

      【解决方案2】:

      我在这篇文章中找到的答案和问题让我追了一段时间。最后,我通过将密钥库导入到我的 Weblogic 服务器上的密钥库中,为我部署到 WebLogic 11g 的应用程序工作:

      C:\bea\jrockit_160_14_R27.6.5-32\jre\bin>keytool -importkeystore -srckeystore \workspace\myProject\webservice.keystore

      然后我将 WebLogic 密钥库的配置更改为指向此密钥库。您可以通过 WL 控制台执行此操作:Environment->Servers->AdminServer->Keystores。 更改Keystores:选择“Custom Identity and Custom Trust”,然后在Identity中填写路径(传入),Trust(传出)部分到您的密钥库位置。在 Windows XP 上,我的位于 \Documents an Settings\my id\.keystore。

      我没有提供密码,我认为它是可选的。

      【讨论】:

        【解决方案3】:

        我认为您可以使用 KeyStore.Builder 以编程方式加载基于密钥库:

        http://java.sun.com/j2se/1.5.0/docs/api/java/security/KeyStore.Builder.html#newInstance%28java.lang.String,%20java.security.Provider,%20java.io.File,%20java.security.KeyStore.ProtectionParameter%29

        所以可能有一个类有一个 web 服务模板或扩展它,然后在你的 spring 配置中设置密钥库的文件路径,并使其成为一个初始化 bean(@PostConstruct 在 Spring 3 中?)然后加载密钥库.

        File f = new File(keyStorePath);
        KeyStore.Builder builder = KeyStore.Builder.newInstance("type",provider,file,protection);
        KeyStore keystore = builder.getKeyStore();
        

        好的 - 要将它与您的 webservicetemplate 一起使用,我认为它必须基于此处记录的密钥库回调:http://static.springsource.org/spring-ws/sites/1.5/reference/html/security.html#d0e4462

        或者也许通过使用可以设置 keystoremanager 的 spring org.springframework.ws.transport.http.HttpsUrlConnectionMessageSender。然后你的 webservicetemplate 就可以使用它了。

        有点像这样:

        <bean id="template" class="org.springframework.ws.client.core.WebServiceTemplate">
            <property name="messageSender">
                <bean class="org.springframework.ws.transport.http.HttpsUrlConnectionMessageSender">
                    <property name=""></property>
                </bean>
            </property>
        </bean>
        

        HTH

        【讨论】:

          【解决方案4】:

          对此线程的回复迟了,但无论如何:请注意,一旦您设置了密钥库和其他所有内容,您可能会惊讶地发现 WebServiceTemplate 似乎不支持 HTTPS 连接!

          确保将messageSender 属性设置为org.springframework.ws.transport.http.CommonsHttpMessageSender。默认的WebServiceMessageSender 实现不支持HTTPS。

          【讨论】:

            【解决方案5】:

            我假设您的意思是要配置 JSSE 使用的密钥库,因为这是模板将使用的。 JSSE 将始终查看 javax.net.ssl.keyStore/javax.net.ssl.keyStorePassword 系统属性以查找密钥库。您可以像这样使用 InitializingBean 在 Spring 中配置这些属性。

            请注意,如果您在应用服务器中运行,则可能在 Spring 初始化之前已经配置了 JSSE。在这种情况下,您需要使用应用服务器接口来设置密钥库——通常在命令行中使用 -D 参数。

            <bean id="jsseInitializer" lazy-init="false" class="com.blah.JsseInitializer">
                    <property name="trustStoreLocation" value="${pnet.batch.trustStore.location}"/>
                    <property name="trustStorePassword" value="${pnet.batch.trustStore.password}"/>
                    <property name="keyStoreLocation" value="${pnet.batch.keyStore.location}"/>
                    <property name="keyStorePassword" value="${pnet.batch.keyStore.password}"/>
            </bean>
            
            
            public class JsseInitializer implements InitializingBean {
            
                private String trustStoreLocation;
                private String trustStorePassword;
                private String keyStoreLocation;
                private String keyStorePassword;
            
                public String getTrustStoreLocation() {
                    return trustStoreLocation;
                }
            
            
                public void setTrustStoreLocation(String trustStoreLocation) {
                    this.trustStoreLocation = trustStoreLocation;
                }
            
            
                public String getTrustStorePassword() {
                    return trustStorePassword;
                }
            
            
                public void setTrustStorePassword(String trustStorePassword) {
                    this.trustStorePassword = trustStorePassword;
                }
            
            
                public String getKeyStoreLocation() {
                    return keyStoreLocation;
                }
            
            
                public void setKeyStoreLocation(String keyStoreLocation) {
                    this.keyStoreLocation = keyStoreLocation;
                }
            
            
                public String getKeyStorePassword() {
                    return keyStorePassword;
                }
            
            
                public void setKeyStorePassword(String keyStorePassword) {
                    this.keyStorePassword = keyStorePassword;
                }
            
                public void afterPropertiesSet() throws Exception {
                    System.setProperty("javax.net.ssl.trustStore", trustStoreLocation);
                    System.setProperty("javax.net.ssl.trustStorePassword", trustStorePassword);
                    System.setProperty("javax.net.ssl.keyStore", keyStoreLocation);
                    System.setProperty("javax.net.ssl.keyStorePassword", keyStorePassword);
            
                }
            }
            

            【讨论】:

              【解决方案6】:

              您应该在用于运行应用服务器的 JDK 的密钥库(可能是 cacerts 文件)中安装所需的证书,使用他们的 keytool 命令。

              这是一个示例命令:

              keytool -import -trustcacerts -alias someAlias -file someCert.crt -keystore yourKeystore
              

              编辑:根据更新后的问题,您可能正在寻找以下内容:http://static.springsource.org/spring-ws/sites/1.5/reference/html/security.html

              【讨论】:

              • @Taylor L - 谢谢,虽然我真的在寻找一种在春季配置密钥库位置的方法。我会更新我的问题以反映这一点。
              • L - 是的,该页面是一个很好的参考。但是我如何将 WebServiceTemplate 与密钥库连接起来......
              【解决方案7】:

              对于 Spring Boot 应用程序

              我发现 Zoltan 的这篇博客很有帮助。

              https://zoltanaltfatter.com/2016/04/30/soap-over-https-with-client-certificate-authentication/

              在下面显示他博客中的代码 sn-ps。

              在 application.properties 中添加所有必需的属性。

              @Value("${key-store}")
              private Resource keyStore;
              
              @Value("${key-store-password}")
              private String keyStorePassword;
              
              @Value("${trust-store}")
              private Resource trustStore;
              
              @Value("${trust-store-password}")
              private String trustStorePassword;
              

              除了为您的实现 WebServiceGatewaySupport 的类设置 Uri、marshaller、unmarshaller 之外,还设置了消息发送器。需要遵循以下步骤。

              使用您的密钥库加载密钥库管理器工厂

               KeyStore ks = KeyStore.getInstance("JKS");
               ks.load(keyStore.getInputStream(), keyStorePassword.toCharArray());
               KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
               keyManagerFactory.init(ks, keyStorePassword.toCharArray());
              

              使用您的信任库加载信任库管理器工厂

               TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
               trustManagerFactory.init(ts);
              

              创建 HttsUrlConnectionMessageSender 实例并使用上面创建的密钥管理器工厂和信任管理器工厂设置密钥和信任管理器。

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

              最后设置消息发送者

                  client.setMessageSender(messageSender);
              

              这里的client是扩展WebServiceGatewaySupport的类

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2012-03-24
                • 1970-01-01
                • 1970-01-01
                • 2020-06-30
                • 1970-01-01
                • 2016-11-05
                • 2021-01-06
                相关资源
                最近更新 更多