wss4j和axis2实现WS-Security
Wss4j是apache开发的,标准实现WS-Security(WebService安全)的开源项目,它提供了用户名令牌环验证(UsernameToken)和传递消息时保证信息的完整性和真实性等一些WebService安全保障。
开发环境准备
在正式开始前还要去下载一个rampart-1.1.mar,下载地址http://www.apache.org/dyn/closer.cgi/ws/rampart/1_1。它是在AXIS2上实现WSS4J必需要的一个组件,需要放到WEB-INF\modules下去。另外,需要把wss4j的相关jar包导入到lib下。?
搭建webservice环境
将axis2.war包拷贝到tomcat安装目录下的webapps目录下。
启动Tomcat(Tomcat5.5\bin\startup.bat),打开浏览器输入并访问:http://127.0.0.1:8080/axis2 来查看是否axis2已经正常工作。
?
三、用KEYTOOL生成一对JKS文件
先我们用keytool生成一对JKS文件, service.jks和client.jks。
service.jks存放了service的私钥和client的公钥。
client.jks存放了client的私钥和service的公钥。
生成时需要设置密码,在此,我们使用apache作为生成的service.jks的私钥和公钥keystore的密码, client.jks的私钥和公钥keystore的密码也同样设置为apache.
四、建立web应用
编写服务器端代码
首先简单介绍Wss4j实现WS-Security功能,很简单就是客户端发送一个字符串,服务器端得到该字符串,同时把字符串在发送给客户端,首先自己建立一个web应用工程。
?
在src下建一个包com.test.wss4j.rempart.demo.services?在这里写一个类SimpleService作为服务器端
该类的内容是:
?
package?com.test.wss4j.demo;
public?class?SimpleService
{
????public?String echo(String arg)
????{
????????return?arg;
????}
}
?
这个类的作用就是接收客户端的字符串,并且把该字符串返回给客户端。
?
这里还有个类,该类是实现UsernameToken和传送信息的安全性和完整性的核心,该类被配置在axis2.xml和service.xml中,从而能得到用户配置的axis2.xml中的信息,和服务器端配置的service.xml的信息。每当客户端发送请求时,它都要首先通过该类获得访问服务端的权限和获得发送数据所需要的加密密码,然后把数据加密发送给服务器端,如果没有权限则不能把数据发送到服务器端。每当服务器端想要把数据传送到客户端时,也要经过此类获得发送数据所需要的加密密码,然后把数据加密返回给客户端,客户端通过解密获得明文信息。
?
它的内容如下:
package com.test.wss4j.demo;
import org.apache.ws.security.WSPasswordCallback;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import java.io.IOException;
public class PWCBHandler implements CallbackHandler
{
????public void handle(Callback[] callbacks) throws IOException,?UnsupportedCallbackException
????????????{
??????????????????????for (int i = 0; i < callbacks.length; i++)
??????????????????????{
??????????????????????????WSPasswordCallback pwcb = (WSPasswordCallback)callbacks[i];
??????????????????????????
??????????????????????????String id = pwcb.getIdentifer();
??????????????????????????if("client".equals(id))
??????????????????????????{
??????????????????????????????pwcb.setPassword("apache");
??????????????????????????}
??????????????????????????else if("service".equals(id))
??????????????????????????{
??????????????????????????????pwcb.setPassword("apache");
??????????????????????????}
????????????????????else
????????????????????{
????????????????????????throw new UnsupportedCallbackException(callbacks[i],?"对不起,您不是授权用户,不能访问该WEB服务!");
????????????????????}
????????????????}
??????????}
}
?
编写服务器端的描述文件services.xml
然后写一个解析该服务器类services.xml文件。该文件的内容如下:
<?xml?version="1.0"?encoding="UTF-8"?>
<service?name="wsc">
????<operation?name="echo">
???????<messageReceiver
????????class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
????</operation>
????<parameter?name="ServiceClass"?locked="false">
???????com.neusoft.wss4j.rempart.demo.services.SimpleService
????</parameter>
????<module?ref="rampart"?/>
????<parameter name="InflowSecurity">
???????<action>
???????????<items>Timestamp Signature</items>
???????????<signaturePropFile>
??????????????keys/service.properties
???????????</signaturePropFile>
???????</action>
????</parameter>
????<parameter name="OutflowSecurity">
???????<action>
???????????<items>Timestamp Signature</items>
???????????<user>service</user>
???????????<passwordCallbackClass>
??????????????com.neusoft.wss4j.demo.PWCBHandler
???????????</passwordCallbackClass>
???????????<signaturePropFile>
??????????????keys/service.properties
???????????</signaturePropFile>
???????????<signatureKeyIdentifier>
??????????????DirectReference
???????????</signatureKeyIdentifier>
???????</action>
????</parameter>
</service>
?
服务器wsc中有几个方法就需要配置几个<operation></operation>
echo为wsc服务器类中的方法。wsc为服务的名字也就是后边的打包服务器端wsc.aar的名字。着重看下红色和粉色字体部分,红色这部分是客户端传来信息用数字签名来解密客户端传过来的加密信息本例通过keys文件夹下的service.properties这个文件找到service.jks对信息进行解密,粉色部分是服务器端把输出向客户端的信息加密用的,本例通过keys文件夹下的service.properties这个文件找到service.jks对信息加密的。
?
service.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=apache
org.apache.ws.security.crypto.merlin.file=keys/service.jks