开发者

Using WebServiceTemplate with a keystore

Is 开发者_如何学Pythonit possible to configure a WebServiceTemplate with a java keystore?

edit

I'm looking for a way to configure the location of the keystore in the spring config


I am posting this answer after six years but to be honest there isn't a single post where a complete and concise solution is provided. All you need is spring-ws-core (2.1.4.RELEASE +) and spring-we-security (2.2.4.RELEASE +) dependencies. The next step is to configure custom keystore and truststore as beans and then inject them to web service template in spring configuration.

<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>

In summery there is no need to write any code, the use case can be easily achieved using spring config.


For spring boot application

I found this blog by Zoltan very helpful.

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

Showing a code snippets below from his blog.

Add all required properties in 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;

And along with setting Uri, marshaller, unmarshaller for your class which is implementing WebServiceGatewaySupport set messagesender. For which below steps need to be followed.

Load Keystore manager factory with your keystore

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

Load Trust store manager factory with your truststore

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

Create instance of HttpsUrlConnectionMessageSender and set key and trust manager using key manager factory and trust manager factory created above.

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

Finally set message sender

    client.setMessageSender(messageSender);

Here client is the class that extends WebServiceGatewaySupport


The answers and the questions that I found in this post kept me chasing my tail for a while. In the end I got this working for an application I deployed to WebLogic 11g by importing the keystore into the keystore on my Weblogic server:

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

Then I changed the configuration for the WebLogic keystore to point to this keystore. You can do this through the WL console: Environment->Servers->AdminServer->Keystores. Change the Keystores: selection to "Custom Identity and Custom Trust", then fill in the path in the Identity(incoming), and Trust(outgoing) sections to your keystore location. On Windows XP, mine was in \Documents an Settings\my id\.keystore.

I didn't provide the passphrase and I believe it is optional.


I think you can programatically load a keystore based using a 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

So maybe have a class that has a webservice template or extends it, then set the file path of the keystore on it in your spring config and make it an inizialing bean (@PostConstruct in Spring 3?) which then loads the keystore.

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

Ok - to actually use it with your webservicetemplate i think it must be based around the keystore callback as documented here: http://static.springsource.org/spring-ws/sites/1.5/reference/html/security.html#d0e4462

Or maybe by using the spring org.springframework.ws.transport.http.HttpsUrlConnectionMessageSender which you can set keystoremanager on. Then that can be used by your webservicetemplate.

A bit like this:

<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


Late reply on this thread but anyway: note that once you have your keystore and everything else set up, you may be shocked to find that the WebServiceTemplate doesn't seem to support HTTPS connections!

Make sure you set the messageSender property to be org.springframework.ws.transport.http.CommonsHttpMessageSender. The default WebServiceMessageSender implementation does not support HTTPS.


I'm assuming you mean you want to configure the keystore used by JSSE, since that is the Template will use. JSSE will always always look at the javax.net.ssl.keyStore/javax.net.ssl.keyStorePassword system properties to find the keystore. You can configure these properties in Spring using an InitializingBean like this.

Note that if you are running in an app server the JSSE may already be configured before Spring initializes. In this case you need to use the app server interface to set the keystore -- usually using -D params on command line.

<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);

    }
}


You should install the certificates you need in the keystore (probably the cacerts file) of the JDK used to run your app server using they keytool command.

Here is an example command:

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

Edit: Based on the updated question it looks like this may be what you are looking for: http://static.springsource.org/spring-ws/sites/1.5/reference/html/security.html

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜