XFire中实现WS-Security完整编 在1.1中已经支持ws-security了。XFire通过wss4j提供ws-security支持。 一、 前提条件: 前提条件要安装Unlimited Strength Jurisdiction Policy(可以在http://java.sun.com/j2se/1.5.0/download.jsp或http://java.sun.com/j2se/1.4.2/download.html下载)和Bouncy Castle(来自http://BouncyCastle.org)。否则会出现无效算法(algorithm)或Key大小(Key Size) 为了能支持WS-Security必须添加两个Handler:inhandlers、outhandlers。 以下必须添加到inHandlers 1、 org.codehaus.xfire.security.wss4j.WSS4JInHandler:执行WS-Security相关的函数; 2、 org.codehaus.xfire.util.dom.DOMInHandler:为WS-Security从StAX 转换成DOM格式。 注:DOMInHandler必须引入Xalan 2.7.0,XFire默认没有引入。 以下添加到outHandlers: 1、 org.codehaus.xfire.security.wss4j.WSS4JOutHandler:执行WS-Security相关的函数; 2、 org.codehaus.xfire.util.dom.DOMOutHandler:为WS-Security从StAX 转换成DOM格式。 二、 安装Unlimited Strength Jurisdiction Policy和Bouncy Castle 1、 安装Unlimited Strength Jurisdiction Policy:把local_policy.jar和US_export_policy.jar两个文件拷贝到:C:\j2re1.4.2\lib\security\下;(如果JRE安装在C:\j2re1.4.2)。 2、 安装Bouncy Castle: (1)、把下载的bcprov-jdk14-119.jar文件拷贝到两个地方: 一个在你安装的JDK目录中,比如:C:\j2sdk1.4.0-rc\jre\lib\ext。另一个在你的JDK运行环境中,比如:C:\Program Files\Java\j2re1.4.0-rc\lib\ext; (2)、还要在对两个java.security进行修改: 我的在 C:\j2sdk1.4.0-rc\jre\lib\security\java.security;C:\Program Files\Java\j2re1.4.0-rc\lib\security\java.security; 在java.security中加入 security.provider.6=org.bouncycastle.jce.provider.BouncyCastleProvider 三、 创建密钥: 1、 通过别名和密码创建私密钥到keystore: keytool -genkey -alias ws_security -keypass keypassword -keystore privatestore.jks -storepass keyStorePassword -dname "cn=ws_security" -keyalg RSA 采用RSA算法进行处理。 2、 证书: keytool -selfcert -alias ws_security -keystore privatestore.jks -storepass keyStorePassword -keypass keypassword 3、 导出公钥到key.rsa: keytool -export -alias ws_security -file key.rsa -keystore privatestore.jks -storepass keyStorePassword 4、 导入公钥到新的keystore中: keytool -import -alias ws_security -file key.rsa -keystore publicstore.jks -storepass keyStorePassword 5、 创建insecurity.properties: 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=keyStorePassword org.apache.ws.security.crypto.merlin.alias.password=keypassword org.apache.ws.security.crypto.merlin.keystore.alias=ws_security org.apache.ws.security.crypto.merlin.file=META-INF/xfire/publicstore.jks 6、 创建outsecurity.properties: 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=keyStorePassword org.apache.ws.security.crypto.merlin.alias.password=keypassword org.apache.ws.security.crypto.merlin.keystore.alias=ws_security org.apache.ws.security.crypto.merlin.file=META-INF/xfire/privatestore.jks 7、 把文件insecurity,outsecurity.properties,privatestore.jks和publicstore.jks复制到META-INF/xfire/下。 有关keytool的使用说明,请查看以下资料: http://www.churchillobjects.com/c/11201e.html http://java.sun.com/j2se/1.4.2/docs/tooldocs/windows/keytool.html http://support.globalsign.net/en/objectsign/java.cfm 四、 实例: 1、 创建服务接口: package example.services; public interface BookService { public String echo(String msg); } 2、 创建服务实现类: package example.services; public class BookServiceImpl implements BookService { public String echo(String msg){ return msg; } } 3、 配制webservices.xml文件: <service> <name>BookService</name> <serviceClass>example.services.BookService</serviceClass> <implementationClass> example.services.BookServiceImpl </implementationClass> <style>wrapped</style> <use>literal</use> <scope>application</scope> <inHandlers> <handler handlerClass="org.codehaus.xfire.util.dom.DOMInHandler" /> <bean class="org.codehaus.xfire.security.wss4j.WSS4JInHandler" xmlns=""> <property name="properties"> <props> <prop key="action">Signature</prop> <prop key="signaturePropFile"> META-INF/xfire/insecurity.properties </prop> <prop key="decryptionPropFile"> META-INF/xfire/insecurity.properties </prop> <prop key="passwordCallbackClass"> example.ws_security.PasswordHandler </prop> </props> </property> </bean> </inHandlers> </service> 4、 创建: package example.ws_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 PasswordHandler implements CallbackHandler { private Map passwords = new HashMap();
public PasswordHandler() { passwords.put("ws_security", "keypassword"); }
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { System.out.println("Handling Password!"); WSPasswordCallback pc = (WSPasswordCallback) callbacks[0]; String id = pc.getIdentifer(); System.out.println("id:"+id+" ,password:"+(String) passwords.get(id)); pc.setPassword((String) passwords.get(id)); } } 5、 客户端实现: package example.test;
import java.lang.reflect.Proxy; import java.net.MalformedURLException;
import org.apache.ws.security.WSConstants; import org.apache.ws.security.handler.WSHandlerConstants; import org.codehaus.xfire.client.Client; import org.codehaus.xfire.client.XFireProxy; import org.codehaus.xfire.client.XFireProxyFactory; import org.codehaus.xfire.security.wss4j.WSS4JOutHandler; import org.codehaus.xfire.service.Service; import org.codehaus.xfire.service.binding.ObjectServiceFactory; import org.codehaus.xfire.util.dom.DOMOutHandler;
import example.services.BookService; import example.ws_security.PasswordHandler;
public class TTTest { private WSS4JOutHandler wsOut; private Service service; private BookService bookservice; private Client client; private static final String SERVICE_URL ="http://localhost:8080/TT/services/BookService"; public TTTest() { //建议采用此种方式进行创建服务(带有服务名,此例为“BookService”) service=new ObjectServiceFactory().create(BookService.class, "BookService", null, null); try { bookservice=(BookService) new XFireProxyFactory().create(service, SERVICE_URL); client = ((XFireProxy) Proxy.getInvocationHandler(bookservice)).getClient(); } catch (MalformedURLException e) { e.printStackTrace(); } wsOut = new WSS4JOutHandler(); wsOut.setProperty(WSHandlerConstants.SIG_PROP_FILE, "META-INF/xfire/outsecurity.properties"); wsOut.setProperty(WSHandlerConstants.ENC_PROP_FILE, "META-INF/xfire/outsecurity.properties"); wsOut.setProperty(WSHandlerConstants.USER, "ws_security"); //wsOut.setProperty("password", "keypassword11"); wsOut.setProperty(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PASSWORD_TEXT); wsOut.setProperty(WSHandlerConstants.PW_CALLBACK_CLASS, PasswordHandler.class.getName()); wsOut.setProperty(WSHandlerConstants.SIG_KEY_ID,"IssuerSerial"); client.addOutHandler(new DOMOutHandler()); client.addOutHandler(wsOut);
String actions =WSHandlerConstants.SIGNATURE; //wsOut.setProperty(WSHandlerConstants.TTL_TIMESTAMP,"30"); wsOut.setProperty(WSHandlerConstants.ACTION, actions); System.out.println(bookservice.echo("Client test msg")); client.close(); } public static void main(String [] args) { new TTTest(); } }
|
|