CXF Message Level Security 博客分类: java
程序员文章站
2024-03-17 08:01:15
...
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.
<!-- applicationContext-server.xml start -->
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<bean id="addressBookServiceImpl" class="com.bruce.cxftest.service.AddressBookServiceImpl" />
<bean id="passwordCallback" class="com.bruce.cxftest.security.ServerPasswordCallback" />
<bean id="saajInInterceptor" class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor" />
<bean id="saajOutInterceptor" class="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor" />
<bean id="logInInterceptor" class="org.apache.cxf.interceptor.LoggingInInterceptor" />
<bean id="logOutInterceptor" class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
<bean id="wss4jInConfiguration" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
<property name="properties">
<map>
<entry key="action" value="UsernameToken Timestamp Encrypt Signature" />
<entry key="decryptionPropFile" value="server_insecurity_enc.properties" />
<entry key="signaturePropFile" value="server_insecurity_sign.properties" />
<entry>
<key>
<value>passwordCallbackRef</value>
</key>
<ref bean="passwordCallback" />
</entry>
</map>
</property>
</bean>
<bean id="wss4jOutConfiguration" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
<property name="properties">
<map>
<entry key="action" value="Timestamp Encrypt Signature" />
<entry key="user" value="apmserver" />
<entry key="encryptionUser" value="apmclient" />
<entry key="encryptionPropFile" value="server_outsecurity_enc.properties" />
<entry key="signaturePropFile" value="server_insecurity_sign.properties" />
<entry>
<key>
<value>passwordCallbackRef</value>
</key>
<ref bean="passwordCallback" />
</entry>
</map>
</property>
</bean>
<jaxws:endpoint id="addressBookService" implementor="#addressBookServiceImpl"
address="/AddressBookService" >
<jaxws:inInterceptors>
<ref bean="logInInterceptor" />
<ref bean="saajInInterceptor" />
<ref bean="wss4jInConfiguration" />
</jaxws:inInterceptors>
<jaxws:outInterceptors>
<ref bean="logOutInterceptor" />
<ref bean="saajOutInterceptor" />
<ref bean="wss4jOutConfiguration" />
</jaxws:outInterceptors>
</jaxws:endpoint>
</beans>
<!-- applicationContext-server.xml end -->
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<String,String> userMap = new HashMap<String,String>();
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.
<!-- applicationContext-client.xml start -->
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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">
<bean id="passwordCallback" class="com.bruce.cxftest.security.ServerPasswordCallback" />
<bean id="saajInInterceptor" class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor" />
<bean id="saajOutInterceptor" class="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor" />
<bean id="wss4jOutConfiguration" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
<property name="properties">
<map>
<entry key="action" value="UsernameToken Timestamp Encrypt Signature" />
<entry key="user" value="apmclient" />
<entry key="encryptionUser" value="apmserver" />
<entry key="signaturePropFile" value="outsecurity_sign.properties" />
<entry key="signatureKeyIdentifier" value="IssuerSerial" />
<entry key="encryptionPropFile" value="outsecurity_enc.properties" />
<entry>
<key>
<value>passwordCallbackRef</value>
</key>
<ref bean="passwordCallback" />
</entry>
</map>
</property>
</bean>
<bean id="wss4jInConfiguration" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
<property name="properties">
<map>
<entry key="action" value="Timestamp Encrypt Signature" />
<entry key="user" value="apmclient" />
<entry key="decryptionPropFile" value="insecurity_enc.properties" />
<entry key="enableSignatureConfirmation" value="true" />
<entry key="signaturePropFile" value="outsecurity_sign.properties" />
<entry key="signatureKeyIdentifier" value="IssuerSerial" />
<entry>
<key>
<value>passwordCallbackRef</value>
</key>
<ref bean="passwordCallback" />
</entry>
</map>
</property>
</bean>
<jaxws:client id="addressBookClient"
serviceClass="com.bruce.cxftest.service.AddressBookService"
address="http://127.0.0.1:9080/cxftest/service/AddressBookService">
<jaxws:outInterceptors>
<ref bean="saajOutInterceptor" />
<ref bean="wss4jOutConfiguration" />
</jaxws:outInterceptors>
<jaxws:inInterceptors>
<ref bean="saajInInterceptor" />
<ref bean="wss4jInConfiguration" />
</jaxws:inInterceptors>
</jaxws:client>
</beans>
<!-- applicationContext-client.xml end -->
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<String,String> userMap = new HashMap<String,String>();
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<String, Object> inProps = new HashMap<String, Object>();
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<String, Object> outProps = new HashMap<String, Object>();
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!
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.
<!-- applicationContext-server.xml start -->
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<bean id="addressBookServiceImpl" class="com.bruce.cxftest.service.AddressBookServiceImpl" />
<bean id="passwordCallback" class="com.bruce.cxftest.security.ServerPasswordCallback" />
<bean id="saajInInterceptor" class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor" />
<bean id="saajOutInterceptor" class="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor" />
<bean id="logInInterceptor" class="org.apache.cxf.interceptor.LoggingInInterceptor" />
<bean id="logOutInterceptor" class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
<bean id="wss4jInConfiguration" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
<property name="properties">
<map>
<entry key="action" value="UsernameToken Timestamp Encrypt Signature" />
<entry key="decryptionPropFile" value="server_insecurity_enc.properties" />
<entry key="signaturePropFile" value="server_insecurity_sign.properties" />
<entry>
<key>
<value>passwordCallbackRef</value>
</key>
<ref bean="passwordCallback" />
</entry>
</map>
</property>
</bean>
<bean id="wss4jOutConfiguration" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
<property name="properties">
<map>
<entry key="action" value="Timestamp Encrypt Signature" />
<entry key="user" value="apmserver" />
<entry key="encryptionUser" value="apmclient" />
<entry key="encryptionPropFile" value="server_outsecurity_enc.properties" />
<entry key="signaturePropFile" value="server_insecurity_sign.properties" />
<entry>
<key>
<value>passwordCallbackRef</value>
</key>
<ref bean="passwordCallback" />
</entry>
</map>
</property>
</bean>
<jaxws:endpoint id="addressBookService" implementor="#addressBookServiceImpl"
address="/AddressBookService" >
<jaxws:inInterceptors>
<ref bean="logInInterceptor" />
<ref bean="saajInInterceptor" />
<ref bean="wss4jInConfiguration" />
</jaxws:inInterceptors>
<jaxws:outInterceptors>
<ref bean="logOutInterceptor" />
<ref bean="saajOutInterceptor" />
<ref bean="wss4jOutConfiguration" />
</jaxws:outInterceptors>
</jaxws:endpoint>
</beans>
<!-- applicationContext-server.xml end -->
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<String,String> userMap = new HashMap<String,String>();
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.
<!-- applicationContext-client.xml start -->
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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">
<bean id="passwordCallback" class="com.bruce.cxftest.security.ServerPasswordCallback" />
<bean id="saajInInterceptor" class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor" />
<bean id="saajOutInterceptor" class="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor" />
<bean id="wss4jOutConfiguration" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
<property name="properties">
<map>
<entry key="action" value="UsernameToken Timestamp Encrypt Signature" />
<entry key="user" value="apmclient" />
<entry key="encryptionUser" value="apmserver" />
<entry key="signaturePropFile" value="outsecurity_sign.properties" />
<entry key="signatureKeyIdentifier" value="IssuerSerial" />
<entry key="encryptionPropFile" value="outsecurity_enc.properties" />
<entry>
<key>
<value>passwordCallbackRef</value>
</key>
<ref bean="passwordCallback" />
</entry>
</map>
</property>
</bean>
<bean id="wss4jInConfiguration" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
<property name="properties">
<map>
<entry key="action" value="Timestamp Encrypt Signature" />
<entry key="user" value="apmclient" />
<entry key="decryptionPropFile" value="insecurity_enc.properties" />
<entry key="enableSignatureConfirmation" value="true" />
<entry key="signaturePropFile" value="outsecurity_sign.properties" />
<entry key="signatureKeyIdentifier" value="IssuerSerial" />
<entry>
<key>
<value>passwordCallbackRef</value>
</key>
<ref bean="passwordCallback" />
</entry>
</map>
</property>
</bean>
<jaxws:client id="addressBookClient"
serviceClass="com.bruce.cxftest.service.AddressBookService"
address="http://127.0.0.1:9080/cxftest/service/AddressBookService">
<jaxws:outInterceptors>
<ref bean="saajOutInterceptor" />
<ref bean="wss4jOutConfiguration" />
</jaxws:outInterceptors>
<jaxws:inInterceptors>
<ref bean="saajInInterceptor" />
<ref bean="wss4jInConfiguration" />
</jaxws:inInterceptors>
</jaxws:client>
</beans>
<!-- applicationContext-client.xml end -->
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<String,String> userMap = new HashMap<String,String>();
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<String, Object> inProps = new HashMap<String, Object>();
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<String, Object> outProps = new HashMap<String, Object>();
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!
上一篇: Java学习之路Day06
推荐阅读
-
CXF Message Level Security 博客分类: java
-
由wsdl生成的java vo类不适合做普通java vo 博客分类: CXF/WebService wsdlwebservicerpcwsdl to java classvo
-
Error message: Selected class file name 'SomeFileName.java' mapped to not java f 博客分类: Intellij IDEA idea
-
spring-security(三)java config-sample之hello world 博客分类: spring security springsecurity
-
spring-security(四)java config-sample之jdbc 博客分类: spring security securityspring
-
AES加密时抛出java.security.InvalidKeyException: Illegal key size or default parameter 博客分类: WEB
-
java.security.UnrecoverableKeyException: Cannot recover key 博客分类: JavaJava Web keytoolca证书获取私钥数字证书
-
轻量级权限管理系统(renren-security) 博客分类: java renrenshirosecurity
-
号外 CXF is JAX-WS certified in Geronimo 2.0-M6-RC1! 博客分类: Java SUNApacheBlog
-
CXF 2.0 RC 发布了 博客分类: Java Apache公告mavenSpringjson