WebService CXF学习(高级篇3):WS-Security

来源:互联网 发布:溺水数据 编辑:程序博客网 时间:2024/05/08 11:31
 这一节我们来探讨一下WebService安全问题,如果所有系统都运行在一个封闭的局域网内,那么可以不考虑网络攻击,拒绝服务,消息篡改,窃取等问题。但通常情况都接入互联网,那么我就得考虑信息安全问题,像前面那样直接将消息裸传,肯定不行。那么,我们就得给消息加密。CXF可以结合WSS4J来对消息安全进行管理,可以使用令牌,X.509认证对消息头或内容进行加密。这节我只对令牌加密做一个简单的描述,我们还以Demo的形式来讲解一下。
    这个Demo是在CXF+Spring+Hibernate的基础修改而成。在这里我只针对修改的东西进行讲解。
Java代码 复制代码 收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>   
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xmlns:jaxws="http://cxf.apache.org/jaxws"  
  5.     xsi:schemaLocation="   
  6.         http://www.springframework.org/schema/beans   
  7.         http://www.springframework.org/schema/beans/spring-beans-2.0.xsd  
  8.         http://cxf.apache.org/jaxws    
  9.         http://cxf.apache.org/schemas/jaxws.xsd">  
  10.     <import resource="classpath:META-INF/cxf/cxf.xml" />   
  11.     <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />   
  12.     <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />   
  13.   
  14.   
  15.     <jaxws:endpoint id="service"  
  16.         implementor="com.itdcl.service.ServiceImpl" address="/Service">   
  17.         <jaxws:inInterceptors>   
  18.             <bean   
  19.                 class="org.apache.cxf.interceptor.LoggingInInterceptor" />   
  20.             <bean   
  21.                 class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor" />   
  22.             <bean   
  23.                 class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">   
  24.                 <constructor-arg>   
  25.                     <map>   
  26.                         <entry key="action" value="UsernameToken" />   
  27.                         <entry key="passwordType"  
  28.                             value="PasswordText" />   
  29.                         <entry key="user" value="cxfServer" />   
  30.                         <entry key="passwordCallbackRef">   
  31.                             <ref bean="serverPasswordCallback" />   
  32.                         </entry>   
  33.                     </map>   
  34.                 </constructor-arg>   
  35.             </bean>   
  36.         </jaxws:inInterceptors>   
  37.     </jaxws:endpoint>   
  38.   
  39.     <bean id="serverPasswordCallback"  
  40.         class="com.itdcl.ws.ServerPasswordCallback" />   
  41.   
  42. </beans>  

    action:UsernameToken指使用用户令牌
    passwordType:PasswordText指密码加密策略,这里直接文本
    user:cxfServer指别名
    passwordCallBackRef:serverPasswordCallback指消息验证

    消息验证类:
Java代码 复制代码 收藏代码
  1. package com.itdcl.ws;   
  2.   
  3. import java.io.IOException;   
  4.   
  5. import javax.security.auth.callback.Callback;   
  6. import javax.security.auth.callback.CallbackHandler;   
  7. import javax.security.auth.callback.UnsupportedCallbackException;   
  8.   
  9. import org.apache.ws.security.WSPasswordCallback;   
  10.   
  11. public class ServerPasswordCallback implements CallbackHandler {   
  12.   
  13.     public void handle(Callback[] callbacks) throws IOException,   
  14.             UnsupportedCallbackException {   
  15.         WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];   
  16.         String pw = pc.getPassword();   
  17.         String idf = pc.getIdentifier();   
  18.         System.out.println("password:"+pw);   
  19.         System.out.println("identifier:"+idf);   
  20.         if (pw.equals("josen") && idf.equals("admin")) {   
  21.             // 验证通过   
  22.         } else {   
  23.             throw new SecurityException("验证失败");   
  24.         }   
  25.     }   
  26.   
  27. }  

     消息验证类通过实现CallbackHandler接口,实现handle方法来进行用户认证。

     那么,客户端又怎样来验证消息是否确呢。
Java代码 复制代码 收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>   
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xmlns:jaxws="http://cxf.apache.org/jaxws"  
  5.     xsi:schemaLocation="   
  6.         http://www.springframework.org/schema/beans   
  7.         http://www.springframework.org/schema/beans/spring-beans-2.0.xsd  
  8.         http://cxf.apache.org/jaxws    
  9.         http://cxf.apache.org/schemas/jaxws.xsd">  
  10.   
  11.     <jaxws:client id="service"  
  12.         address="http://localhost:9999/cxf/Service"  
  13.         serviceClass="com.itdcl.service.IService">   
  14.         <jaxws:outInterceptors>   
  15.             <bean   
  16.                 class="org.apache.cxf.interceptor.LoggingOutInterceptor" />   
  17.             <bean   
  18.                 class="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor" />   
  19.             <bean   
  20.                 class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">   
  21.                 <constructor-arg>   
  22.                     <map>   
  23.                         <entry key="action" value="UsernameToken" />   
  24.                         <entry key="passwordType"  
  25.                             value="PasswordText" />   
  26.                         <entry key="user" value="cxfClient" />   
  27.                         <entry key="passwordCallbackRef">   
  28.                             <ref bean="clientPasswordCallback" />   
  29.                         </entry>   
  30.                     </map>   
  31.                 </constructor-arg>   
  32.             </bean>   
  33.         </jaxws:outInterceptors>   
  34.     </jaxws:client>   
  35.   
  36.     <bean id="clientPasswordCallback"  
  37.         class="com.itdcl.ws.ClientPasswordCallback" />   
  38. </beans>  


    客户端在发送SOAP时对消息对认证,策略跟服务端一样。但是认证类有所区别:
Java代码 复制代码 收藏代码
  1. package com.itdcl.ws;   
  2.   
  3. import java.io.IOException;   
  4.   
  5. import javax.security.auth.callback.Callback;   
  6. import javax.security.auth.callback.CallbackHandler;   
  7. import javax.security.auth.callback.UnsupportedCallbackException;   
  8.   
  9. import org.apache.ws.security.WSPasswordCallback;   
  10.   
  11. public class ClientPasswordCallback implements CallbackHandler {   
  12.   
  13.     public void handle(Callback[] callbacks) throws IOException,   
  14.             UnsupportedCallbackException {   
  15.         for(int i=0;i<callbacks.length;i++)   
  16.         {   
  17.              WSPasswordCallback pc = (WSPasswordCallback)callbacks[i];   
  18.              pc.setPassword("josen");   
  19.              pc.setIdentifier("admin");   
  20.         }   
  21.     }   
  22.   
  23. }  

     客户端在发送消息,设置好用户名和密码。服务端用相应的用户名和密码进行验证。

     令牌验证就如此简单。