CXF Message Level Security

The firsts:Environment

1.Operating System Version :Fedora14
2.Eclipse Version:J2ee版3.5
3.jdk Version:jdk1.6
4.maven local repository:/var/javaproject/repo
5.tomcat Version:1.6
6.tomcat Port:9080
7.The Web service server and client use CXF can work already. refer to CXF用户认证

The second step:Create X509 certificate store
Window batch scriptt file
create a dos batch execute file name generateKeyPair.bat and input the following content
rem ************** generateKeyPair.bat ********** start
rem @echo off
echo alias %1
echo keypass %2
echo keystoreName %3
echo KeyStorePass %4
echo keyName %5
echo keyName %5
keytool -genkey -alias %1 -keypass %2 -keystore %3 -storepass %4 -dname "cn=%1" -keyalg RSA
keytool -selfcert -alias %1 -keystore %3 -storepass %4 -keypass %2
keytool -export -alias %1 -file %5 -keystore %3 -storepass %4
rem ************** generateKeyPair.bat ********** end
create a dos batch execute file name generateServerKey.bat and input the following content:
rem ************** generateServerKey.bat ********** start
call generateKeyPair.bat apmserver apmserverpass serverStore.jks keystorePass serverKey.rsa
call generateKeyPair.bat apmclient apmclientpass clientStore.jks keystorePass clientKey.rsa
keytool -import -alias apmserver -file serverKey.rsa -keystore clientStore.jks -storepass keystorePass -noprompt
keytool -import -alias apmclient -file clientKey.rsa -keystore serverStore.jks -storepass keystorePass -noprompt
rem ************** generateServerKey.bat ********** end

Linux shell scriptt :
create a Linux shell scriptt file name generateKeyPair.sh and input the following content:
# ******************* generateKeyPair.sh start ***********
#!/bin/bash
echo alias $1
echo keypass $2
echo keystoreName $3
echo KeyStorePass $4
echo keyName $5
echo keyName $5
keytool -genkey -alias $1 -keypass $2 -keystore $3 -storepass $4 -dname "cn=$1" -keyalg RSA
keytool -selfcert -alias $1 -keystore $3 -storepass $4 -keypass $2
keytool -export -alias $1 -file $5 -keystore $3 -storepass $4
# ******************* generateKeyPair.sh end ***********

create a Linux shell scriptt file name generateServerKey.sh then input the following content:
# ******************* generateServerKey.sh start ***********
#!/bin/bash
./generateKeyPair.sh apmserver apmserverpass serverStore.jks keystorePass serverKey.rsa
./generateKeyPair.sh apmclient apmclientpass clientStore.jks keystorePass clientKey.rsa
keytool -import -alias apmserver -file serverKey.rsa -keystore clientStore.jks -storepass keystorePass -noprompt
keytool -import -alias apmclient -file clientKey.rsa -keystore serverStore.jks -storepass keystorePass -noprompt
# ******************* generateServerKey.sh end ***********

3.execute the generateServerKey.sh on Linux(generateServerKey.bat on windows) then you will get two key store file clientStore.jks and serverStore.jks. As show on the shell scriptt the user name and password is:
Server:apmserver / apmserverpass
Client:apmclient / apmclientpass

The third step:Configure Server
Copy the serverStore.jks to the resource fold of the web project, The root fold of resource fold, That is the same fold as the file applicationContext-server.xml.
Create a properties file named server_insecurity_enc.properties in the same fold for server encryption then input the following content:
#-- server_insecurity_enc.properties start
org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.type=jks
org.apache.ws.security.crypto.merlin.keystore.password=keystorePass
org.apache.ws.security.crypto.merlin.alias.password=apmserverpass
org.apache.ws.security.crypto.merlin.keystore.alias=apmserver
org.apache.ws.security.crypto.merlin.file=serverStore.jks
#-- server_insecurity_enc.properties end

Create a properties file named server_insecurity_sign.properties in the same fold for server signature then input the following content:
#-- server_insecurity_enc.properties start
org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.type=jks
org.apache.ws.security.crypto.merlin.keystore.password=keystorePass
org.apache.ws.security.crypto.merlin.keystore.alias=apmserver
org.apache.ws.security.crypto.merlin.file=serverStore.jks
#-- server_insecurity_enc.properties end

Create a properties file named sserver_outsecurity_enc.properties in the same fold for server out encryption then input the following content:
#-- server_outsecurity_enc.properties start
org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.type=jks
org.apache.ws.security.crypto.merlin.keystore.password=keystorePass
org.apache.ws.security.crypto.merlin.file=serverStore.jks
#-- server_outsecurity_enc.properties end

alter the service definition file applicationContext-server.xml.



xmlns:context="http://www.springframework.org/schema/context"
xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">























passwordCallbackRef


















passwordCallbackRef







address="/AddressBookService" >
















6.alter the user name and password call back class:

//---- ServerPasswordCallback.java start
package com.bruce.cxftest.security;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.ws.security.WSPasswordCallback;
public class ServerPasswordCallback implements CallbackHandler {
Map userMap = new HashMap();
public ServerPasswordCallback(){
userMap.put("apmserver", "apmserverpass");
userMap.put("apmclient", "apmclientpass");
}
public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException {
WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
if (userMap.containsKey(pc.getIdentifier())) {
pc.setPassword(userMap.get(pc.getIdentifier()));
}
}
}
//---- ServerPasswordCallback.java end

The fourth step :configure client
Copy the clientStore.jks to the resource fold of the client project, The root fold of resource fold, That is the same fole as the file applicationContext-client.xml.
Create a properties file named insecurity_enc.properties in the same fold for server encryption then input the following content:
#-- insecurity_enc.properties start
org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.type=jks
org.apache.ws.security.crypto.merlin.keystore.password=keystorePass
org.apache.ws.security.crypto.merlin.alias.password=apmclientpass
org.apache.ws.security.crypto.merlin.keystore.alias=apmclient
org.apache.ws.security.crypto.merlin.file=clientStore.jks
#-- insecurity_enc.properties end

Create a properties file named outsecurity_enc.properties in the same fold for server signature then input the following content:
#-- outsecurity_enc.properties start
org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.type=jks
org.apache.ws.security.crypto.merlin.keystore.password=keystorePass
org.apache.ws.security.crypto.merlin.alias.password=apmclientpass
org.apache.ws.security.crypto.merlin.keystore.alias=apmclient
org.apache.ws.security.crypto.merlin.file=clientStore.jks
#-- outsecurity_enc.properties end

Create a properties file named outsecurity_sign.properties in the same fold for server out encryption then input the following content:
#-- outsecurity_sign.properties start
org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.type=jks
org.apache.ws.security.crypto.merlin.keystore.password=keystorePass
org.apache.ws.security.crypto.merlin.alias.password=apmclientpass
org.apache.ws.security.crypto.merlin.keystore.alias=apmclient
org.apache.ws.security.crypto.merlin.file=clientStore.jks
#-- outsecurity_sign.properties end

alter the client definition file applicationContext-client.xml.


xmlns:context="http://www.springframework.org/schema/context"
xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd">














passwordCallbackRef

















passwordCallbackRef






serviceClass="com.bruce.cxftest.service.AddressBookService"
address="http://127.0.0.1:9080/cxftest/service/AddressBookService">












6.alter the user name and password call back class:

//---- ServerPasswordCallback.java start
package com.bruce.cxftest.security;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.ws.security.WSPasswordCallback;
public class ServerPasswordCallback implements CallbackHandler {
Map userMap = new HashMap();
public ServerPasswordCallback(){
userMap.put("apmserver", "apmserverpass");
userMap.put("apmclient", "apmclientpass");
}
public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException {
WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
if (userMap.containsKey(pc.getIdentifier())) {
pc.setPassword(userMap.get(pc.getIdentifier()));
}
}
}
//---- ServerPasswordCallback.java end

7. create a client class not use spring.
//--- CxfWsTestClient.java start
package com.bruce.cxftest.client;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import javax.xml.namespace.QName;
import javax.xml.ws.BindingProvider;
import org.apache.cxf.binding.soap.saaj.SAAJInInterceptor;
import org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor;
import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor;
import org.apache.ws.security.handler.WSHandlerConstants;
import com.bruce.cxftest.dto.Phone;
import com.bruce.cxftest.security.ServerPasswordCallback;
import com.bruce.cxftest.service.AddressBookService;
import com.bruce.cxftest.service.AddressBookService_Service;
public class CxfWsTestClient {
public static void main(String[] args) {
try {
URL wsdlAdd = new URL("http://127.0.0.1:9080/cxftest/service/AddressBookService?wsdl");
QName SERVICE = new QName("http://www.bruce.com/cxftest/service", "AddressBookService");
AddressBookService_Service gs = new AddressBookService_Service(wsdlAdd,SERVICE);
AddressBookService greeter = gs.getAddressBookService();
org.apache.cxf.endpoint.Client client = ClientProxy.getClient(greeter);
org.apache.cxf.endpoint.Endpoint cxfEndpoint = client.getEndpoint();
SAAJInInterceptor saajInInterceptor = new SAAJInInterceptor();
cxfEndpoint.getInInterceptors().add(saajInInterceptor);
Map inProps = new HashMap();
inProps.put(WSHandlerConstants.ACTION, WSHandlerConstants.TIMESTAMP + " " + WSHandlerConstants.ENCRYPT + " " + WSHandlerConstants.SIGNATURE);
inProps.put(WSHandlerConstants.USER, "apmclient");
inProps.put(WSHandlerConstants.DEC_PROP_FILE, "insecurity_enc.properties");
inProps.put(WSHandlerConstants.ENABLE_SIGNATURE_CONFIRMATION, "true");
inProps.put(WSHandlerConstants.SIG_PROP_FILE, "outsecurity_sign.properties");
inProps.put(WSHandlerConstants.SIG_KEY_ID, "IssuerSerial");
inProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, ServerPasswordCallback.class.getName());
WSS4JInInterceptor wssIn = new WSS4JInInterceptor(inProps);
cxfEndpoint.getInInterceptors().add(wssIn);
SAAJOutInterceptor saajOutInterceptor = new SAAJOutInterceptor();
cxfEndpoint.getOutInterceptors().add(saajOutInterceptor);
Map outProps = new HashMap();
outProps.put(WSHandlerConstants.ACTION,WSHandlerConstants.USERNAME_TOKEN
+ " " + WSHandlerConstants.TIMESTAMP
+ " " + WSHandlerConstants.ENCRYPT
+ " " + WSHandlerConstants.SIGNATURE);
outProps.put(WSHandlerConstants.USER, "apmclient");
outProps.put(WSHandlerConstants.ENCRYPTION_USER, "apmserver");
outProps.put(WSHandlerConstants.SIG_PROP_FILE, "outsecurity_sign.properties");
outProps.put(WSHandlerConstants.SIG_KEY_ID, "IssuerSerial");
outProps.put(WSHandlerConstants.ENC_PROP_FILE, "insecurity_enc.properties");
outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, ServerPasswordCallback.class.getName());
WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps);
cxfEndpoint.getOutInterceptors().add(wssOut);
AddressBookService service =(AddressBookService) greeter;
System.out.println("#############Client getPhone##############");
Phone phone = service.getPhone("zph");
System.out.println("AreaCode:" + phone.getAreaCode());
System.out.println("Exchange:" + phone.getExchange());
System.out.println("Number:" + phone.getNumber());
} catch (Exception e) {
e.printStackTrace();
}
}
}
//--- CxfWsTestClient.java end

The fifth step: run and debug
1.ope a Console and change directory to cxftest_build,Run the following maven command:
$mvn clean install
2.Deploy the wea package to Tomcat webapps fold' subfold cxftest.
3.start Tomcat
4.start class SpringUsersWsClient or CxfWsTestClient in the project cxftest_client and you will see the below out put information:
AreaCode:120
Exchange:10
Number:10
That means you have successful!

你可能感兴趣的:(CXF Message Level Security)