基于SOAP的Web安全调用机制-----Axis2+SOAP Header验证方法实践【已经试验】

文章来源:http://blog.csdn.net/wwwgeyang777/article/details/19964999


在前一篇文章:Axis2+Rampart(WSS4J)实现UsernameToken认证方式的WS-Security(基于SOAP的Web安全调用机制)

http://blog.csdn.net/wwwgeyang777/article/details/19928631

介绍了Axis2+Rampart(WSS4J)实现UsernameToken认证方式的WS-Security,感觉能满足大部分应用的安全需求了,就是相对比较繁琐,而且关于传输消息的封装等都在黑盒中完成了,被框架完全绑架了,实在是不可控。

那有没有简单点的又完全是由开发者控制的安全验证方式呢?答案是:Of course!

先理解下WSS4J的工作方式:WSS4J在Web Services框架中以handler方式工作,在发送SOAP消息前进行签名、加入认证凭据和加密,在收到SOAP消息后进行解密、认证和验证签名等安全工作。使用者可以自己编写handler处理SOAP消息以保证安全。

在我看来,WSS4J的方式说白了,就是在SOAP请求的Header中添加验证信息,然后服务端在相应的服务中解析Header,再进行校验,这就是最简单的原理。

既然原理清楚了,下面就来实践吧。

 

服务端

服务端就要在每个方法里面加上解析SOAP Header,并进行安全校验的代码即可,记住,是每一个方法里面都加,是everyone

虽然是每一都需要添加校验代码,但庆幸的是,校验过程都是一致的,实现一个通用的方法,每次调用就行。

这里给出一个校验方法的代码:

 

[java]  view plain copy print ?
  1. import java.util.Iterator;  
  2. import org.apache.axiom.om.OMElement;  
  3. import org.apache.axis2.AxisFault;  
  4. import org.apache.axis2.context.MessageContext;  
  5.   
  6. public class LoginCheck  
  7. {  
  8.     /** 
  9.      * 〈一句话功能简述〉 〈功能详细描述〉 
  10.      *  
  11.      * @throws AxisFault 
  12.      */  
  13.     public static void checkUserPwd() throws AxisFault  
  14.     {  
  15.         MessageContext msgContext = MessageContext.getCurrentMessageContext();  
  16.         // 获取Head  
  17.         Iterator list = (Iterator) msgContext.getEnvelope().getHeader()  
  18.                 .getFirstElement().getChildren();  
  19.         String Username = "";  
  20.         String Password = "";  
  21.         while (list.hasNext())  
  22.         {  
  23.             OMElement element = (OMElement) list.next();  
  24.             if (element.getLocalName().equals("Username"))  
  25.             {  
  26.                 Username = element.getText();  
  27.             }  
  28.             if (element.getLocalName().equals("Password"))  
  29.             {  
  30.                 Password = element.getText();  
  31.             }  
  32.         }  
  33.         if (!Username.equals("toone") || !Password.equals("111111"))  
  34.         {  
  35.             throw new AxisFault(  
  36.                     " Authentication Fail! Check username/password ");  
  37.         }  
  38.     }  
  39. }  

 之后在服务中的每个方法里面加上一句代码,只要一句就行:

[java]  view plain copy print ?
  1. //当客户端调用该方法时,在此处先进行用户名和密码校验,如果校验通过则继续后续逻辑处理,如果不通过则抛出异常。   
  2.    LoginCheck.checkUserPwd();   

服务端就这么简单,下面再说说客户端。

 

 

客户端

 

客户端也不难,就是往SOAPHeader中添加相应字段就行,网上很多代码可以参考。

这里是我用到的代码:

 

[java]  view plain copy print ?
  1. import org.apache.axiom.om.OMAbstractFactory;   
  2. import org.apache.axiom.om.OMElement;   
  3. import org.apache.axiom.om.OMFactory;   
  4. import org.apache.axiom.om.OMNamespace;  
  5.   
  6. public class HeaderOMElement {   
  7.  /** 
  8.  * 〈一句话功能简述〉 
  9.  * 〈功能详细描述〉  
  10.  *  @return     
  11. */  
  12. public static OMElement createHeaderOMElement(){   
  13.   OMFactory factory = OMAbstractFactory.getOMFactory();   
  14.      OMNamespace SecurityElementNamespace = factory.createOMNamespace("http://handler.com","wsse");   
  15.         OMElement authenticationOM = factory.createOMElement("Authentication",   
  16.                 SecurityElementNamespace);   
  17.         OMElement usernameOM = factory.createOMElement("Username",   
  18.                 SecurityElementNamespace);   
  19.         OMElement passwordOM = factory.createOMElement("Password",   
  20.                 SecurityElementNamespace);   
  21.         usernameOM.setText("toone");   
  22.         passwordOM.setText("111111");   
  23.         authenticationOM.addChild(usernameOM);   
  24.         authenticationOM.addChild(passwordOM);   
  25.         return authenticationOM;   
  26.  }   
  27. }   

 

然后在需要调用服务的时候,将创建得到的OMElement附加上去就行了。

这里也给出代码参考:

 

[java]  view plain copy print ?
  1. RPCServiceClient client = new RPCServiceClient();  
  2.   
  3. // 向Soap Header中添加校验信息  
  4. client.addHeader(HeaderOMElement.createHeaderOMElement());   

其他调用的Web服务的代码参考我上一篇文章就行了,不在重复写了。

 

WSS4J VS SOAP Header

最后,和上篇文章中的方法做个简单的比较。

WSS4J方法是采用回调的机制,面向整个服务的,不需要修改服务中具体的方法。

SOAP Header方法更直观,但是需要在每一个方法内部都进行处理,增加了冗余。

  

如果想把这两种方法的好处结合来有办法吗?具体来说就是也在SOAP Header中添加校验信息,但不需要在每个方法中进行校验,也采用回调机制,而且完全由开发者进行控制可以吗?

我想肯定是有的,两种思路:

1)WSS4J源代码拿过来,自己修改;

2)Axis2中增加module的方法,由于对这种机制不太了解就不发表什么意见了,只是个人感觉是靠谱的,就写出来供大家参考,仅此而已。

 

到这里,文章就写完了,如果以后还有什么进展的话,再记录。


你可能感兴趣的:(基于SOAP的Web安全调用机制-----Axis2+SOAP Header验证方法实践【已经试验】)