说明:此处的用户身份认证不是基于证书系统的身份认证,如果需要通过证书系统进行身份认证,请使用rampart。
用户身份认证是很多业务系统必须具备的功能,webService也一样,经过本人这几天的学习研究,发现axis2的安全模块rampart不支持基于业务的用户身份认证,只能是基于证书的身份认证,而很多情况下,我们是需要基于业务用户的身份认证的,甚至需要与CAS、SHIRO等安全框架进行整合,这时rampart模块就派不上用场了。而单独的handler,经本人实际测试,在加上后,客户端直接就不能调用服务,还好axis2提供了模块(module)扩展,我们可以自己编写扩展模块来实现这一功能。
废话不多说,现在就让我们开始自己的基于业务用户的身份认证吧。要实现这个功能,我们需要做三件事:1、实现基于业务用户的身份认证的扩展模块,2、在服务端加载扩展模块,3、在客户端调用时,往soap头中添加身份信息。
一、实现基于业务用户的身份认证的扩展模块
这个很好实现,首先,我们需要新建一个普通的JAVA工程,新建两个类,一个是module另一个是handler。module类必须实现org.apache.axis2.modules.Module接口,可以不用具体实现任何接口方法,除非您的扩展模块有初始化及销毁的操作。这个是AXIS2架构要求的。
handler类必须继承org.apache.axis2.handlers.AbstractHandler基类。实现invoke方法,具体的用户身份认证逻辑在此方法中实现。
public InvocationResponse invoke(MessageContext arg0) throws AxisFault {
checkUserPwd(arg0);
return InvocationResponse.CONTINUE;
}
接下来,我们需要编写module.xml,向axis2表明我们扩展的模块的实现是什么。这个文件需要我们在src目录下新建META-INF文件夹,并将这个文件放到META-INF文件夹下。
<module name="logging" class="com.dbw.checker.UserCheckModule">
<InFlow>
<handler name="InFlowLogHandler" class="com.dbw.checker.UserCheckHandler">
<order phase="loggingPhase"/>
</handler>
</InFlow>
</module>
在module.xml中,除了<InFlow>外,还有<OutFlow>,<InFaultFlow>和<OutFaultFlow>,分别对应入、出、入错误、出错误四个流程,我们可以根据需要进行配置,像本人现在这个需求,只要在请求进入时进行验证,因此只要配置<InFlow>即可。
最后,我们可以使用jar命令或eclipse的导出jar功能,导出模块,注意:axis2模块文件的扩展名必须是.mar。
二、使用身份认证模块
在创建了身份认证扩展模块后,下一步就是要使用它。
1、将身份认证模块的mar文件复制到modules目录,如果此目录下有models.list文件,在此文件中增加身份认证模块的文件名。
2、在axis2.xml的<InFlow>的最后添加phase,像我的这个为<phase name="UserCheckPhase"/>。
3、修改services.xml文件,在需要身份认证的服务中引用身份认证模块,<module ref="logging"/>。
三、在客户端调用服务
通过以上两个大的步骤,我们就完成了服务端的开发工作,这时我们可以通过axis2的code generator功能,生成供客户端调用的stub。当我们什么都不修改的情况下,会发现调用失败,这是因为我们的客户端的SOAP头中没有包含用户身份信息。
1、改造stub
/**
* 客户端增加soap头信息
*
* @param sfunc 方法名,注意大小写
* @param suser 用户名
* @param spass 密码
*/
public void addClientSoapHeader(String sfunc, String suser, String spass) {
OMElement header = HeaderOMElement.createHeaderOMElement(
"http://test.com", sfunc, suser, spass);
_serviceClient.addHeader(header);
}
2、在调用具体方法前在SOAP头中添加用户身份信息
CalculateServiceStub client = new CalculateServiceStub();
client.addClientSoapHeader("sum", "toone", "111111");
本博文中的例子的下载地址: