Before adding WS-Security to your web services, you must make sure to have:
- Access to a certificate authority (CA) - either your own using OpenSSL for example or an external one like CACert
- Acess to keytool (usually through your Java SDK)
Securing a server
This is quite easy. You need first to create a keystore with a key pair. During that process you will be asked for passwords for protecting your keystore and private key. Let's choose 'groovyws' for both of them. This can be done for example with:
keytool -genkey -keyalg RSA -dname "C=FR, O=GroovyWS Inc, OU=GroovyWS Test Centre, CN=Server" -alias server \ -keystore Server.jks
Then you need to generate the Certificate Signing Request like this:
keytool -certreq -alias server -file ServerCertificateRequest.pem -keystore Server.jks
You need to get the server certificate from your CA using the newly generated request. Let's assume you get back the file named ServerCertificate.pem. You need to include that certificate into your keystore. Ususaly this won't be possible unless your keystore contains the certificate of your CA. Let's add those two certificates:
keytool -import -alias TheCA -file TheCACert.pem -keystore Server.jks keytool -import -alias server -file ServerCertificate.pem -keystore Server.jks
You are now ready to start your server:
Map<String, String> mapServer = [ "https.keystore":"path/to/Server.jks", "https.keystore.pass":"groovyws", "https.truststore":"", "https.truststore.pass":"" ] server = new WSServer(myServiceUrl) server.setSSL(mapServer) server.setClientAuthentication(false) server.start()
In the above example, the client authentication is not required. If you turn the flag to true (or omit the line, it is true by default), the client must trust the server, you therefore have to provide a keystore containing the server certificate.
keytool -import -alias server -file ServerCertificate.pem -keystore TrustingTheServer.jks
Map<String, String> mapClient = [ "https.keystore":"", "https.keystore.pass":"", "https.truststore":"path/to/TrustingTheServer.jks", "https.truststore.pass":"client" ] def proxy = new WSClient(myServiceUrl+"?wsdl", this.class.classLoader) proxy.setSSLProperties(mapClient) proxy.initialize() assert proxy.add(2.0 as double, 5.0 as double) == 7.0 assert proxy.square(4.0 as double) == 16.0
You may also setup more complex configurations where both the client & server need to trust each others ...