cxf + spring 的WS-Security示例(一)

来源:互联网 发布:淘宝交易成功数据 编辑:程序博客网 时间:2024/05/30 02:52

在按照网上的例子进行配置用户名令牌的例子,在server端的回调函数中获取的password 却一直是空,搜索了好半天,才找到(这个是MD5加密的):

WSPasswordCallback 的passwordType属性和password 属性都为null,你只能获得用户名(identifier),一般这里的逻辑是使用这个用户名到数据库中查询其密码,然后再设置到password 属性,WSS4J 会自动比较客户端传来的值和你设置的这个值。你可能会问为什么这里CXF 不把客户端提交的密码传入让我们在ServerPasswordCallbackHandler 中比较呢?这是因为客户端提交过来的密码在SOAP 消息中已经被加密为MD5 的字符串,如果我们要在回调方法中作比较,那么第一步要做的就是把服务端准备好的密码加密为MD5 字符串,由于MD5 算法参数不同结果也会有差别,另外,这样的工作CXF 替我们完成不是更简单吗?

 

根据上面说的,我获取的password 为null,所以这里就不用自己判断密码了,只要验证用户名后,在设置密码就可以自动验证了,代码如下:

public class ServerPasswordCallback implements CallbackHandler {    
    
     public void handle(Callback[] callbacks) throws IOException,    
              UnsupportedCallbackException {    
          WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];    
          String pw = pc.getPassword();    
          String idf = pc.getIdentifier();    
          System.out.println("password:"+pw);    
          System.out.println("identifier:"+idf);  
          if(idf.endsWith("admin")){
           pc.setPassword("admin");
          }
      }    
    
 }

以下是源代码:

HelloWorld.java

[java] view plaincopy
  1. package com.mms.webservice;  
  2. import javax.jws.WebService;  
  3. @WebService  
  4. public interface HelloWorld {   
  5.     String sayHi(String text);   
  6. }  

HelloWorldImpl.java

[java] view plaincopy
  1. package com.mms.webservice;  
  2. import javax.annotation.Resource;  
  3. import javax.jws.WebService;  
  4. import javax.servlet.http.HttpServletRequest;  
  5. import javax.servlet.http.HttpSession;  
  6. import javax.xml.ws.WebServiceContext;  
  7. import javax.xml.ws.handler.MessageContext;  
  8. import org.apache.cxf.transport.http.AbstractHTTPDestination;  
  9.   
  10. @WebService  
  11. public class HelloWorldImpl implements HelloWorld {   
  12.     public String sayHi(String text) {  
  13.         return "Hello " + text;  
  14.     }  
  15. }  

ServerPasswordCallback.java

[java] view plaincopy
  1. package com.mms.webservice.test;  
  2. import java.io.IOException;  
  3. import java.util.HashMap;  
  4. import java.util.Map;  
  5. import javax.security.auth.callback.Callback;  
  6. import javax.security.auth.callback.CallbackHandler;  
  7. import javax.security.auth.callback.UnsupportedCallbackException;  
  8. import org.apache.ws.security.WSPasswordCallback;  
  9. import org.apache.ws.security.WSSecurityException;  
  10.   
  11. public class ServerPasswordCallback implements CallbackHandler {  
  12.   
  13.     private Map<String, String> passwords = new HashMap<String, String>();  
  14.   
  15.     public ServerPasswordCallback() {  
  16.         passwords.put("admin""admin");  
  17.         passwords.put("test""test");  
  18.     }  
  19.   
  20.     public void handle(Callback[] callbacks) throws IOException,  
  21.             UnsupportedCallbackException {  
  22.         System.out.println("server:callbacks.length-"+callbacks.length);  
  23.         for (int i = 0; i < callbacks.length; i++) {  
  24.             WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];  
  25.             if (!passwords.containsKey(pc.getIdentifier()))  
  26.                 try {  
  27.                     throw new WSSecurityException("user not match");  
  28.                 } catch (WSSecurityException e) {  
  29.                     e.printStackTrace();  
  30.                 }  
  31.             String pass = passwords.get(pc.getIdentifier());  
  32.             pc.setPassword(pass);  
  33.         }  
  34.     }  
  35.   
  36. }  

ClientPasswordCallback .java

[java] view plaincopy
  1. package com.mms.client;  
  2. import java.io.IOException;  
  3. import java.util.HashMap;  
  4. import java.util.Map;  
  5. import javax.security.auth.callback.Callback;  
  6. import javax.security.auth.callback.CallbackHandler;  
  7. import javax.security.auth.callback.UnsupportedCallbackException;  
  8. import org.apache.ws.security.WSPasswordCallback;  
  9. import org.apache.ws.security.WSSecurityException;  
  10.   
  11. public class ClientPasswordCallback implements CallbackHandler {  
  12.   
  13.     private Map<String, String> passwords = new HashMap<String, String>();  
  14.   
  15.     public ClientPasswordCallback() {  
  16.         passwords.put("admin""admin");  
  17.         passwords.put("test""test");  
  18.     }  
  19.   
  20.     public void handle(Callback[] callbacks) throws IOException,  
  21.             UnsupportedCallbackException {  
  22.         System.out.println("client:callbacks.length-"+callbacks.length);  
  23.         for (int i = 0; i < callbacks.length; i++) {  
  24.             WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];  
  25.             int usage = pc.getUsage();  
  26.             if (!passwords.containsKey(pc.getIdentifier()))  
  27.                 try {  
  28.                     throw new WSSecurityException("user not exists ");  
  29.                 } catch (WSSecurityException e) {  
  30.                     e.printStackTrace();  
  31.                 }  
  32.             String pass = passwords.get(pc.getIdentifier());  
  33.             if (usage == WSPasswordCallback.USERNAME_TOKEN && pass != null) {  
  34.                 System.out.println("client:pass"+pass);  
  35.                 pc.setPassword(pass);  
  36.                 return;  
  37.             }  
  38.         }  
  39.     }  
  40.   
  41. }  

web.xml

[html] view plaincopy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <web-app version="2.5"   
  3.     xmlns="http://java.sun.com/xml/ns/javaee"   
  4.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
  5.     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   
  6.     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">  
  7.   <welcome-file-list>  
  8.     <welcome-file>index.jsp</welcome-file>  
  9.   </welcome-file-list>  
  10.   <context-param>  
  11.         <param-name>contextConfigLocation</param-name>  
  12.         <param-value>  
  13.             classpath:server.xml classpath:client.xml  
  14.         </param-value>  
  15.     </context-param>  
  16.   
  17.     <listener>  
  18.         <listener-class>  
  19.             org.springframework.web.context.ContextLoaderListener  
  20.         </listener-class>  
  21.     </listener>  
  22.   
  23.     <servlet>  
  24.         <servlet-name>CXFServlet</servlet-name>  
  25.         <servlet-class>  
  26.             org.apache.cxf.transport.servlet.CXFServlet  
  27.         </servlet-class>  
  28.     </servlet>  
  29.   
  30.     <servlet-mapping>  
  31.         <servlet-name>CXFServlet</servlet-name>  
  32.         <url-pattern>/*</url-pattern>  
  33.     </servlet-mapping>  
[html] view plaincopy
  1. </web-app>  

 

客户端spring配置文件:client.xml

[html] view plaincopy
  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" xmlns:jaxws="http://cxf.apache.org/jaxws"  
  4.     xsi:schemaLocation="  
  5.                        http://www.springframework.org/schema/beans  
  6.                        http://www.springframework.org/schema/beans/spring-beans.xsd  
  7.                        http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">  
  8.   
  9.     <!-- 定义客户端的拦截器对象  -->  
  10.     <bean id="logIn" class="org.apache.cxf.interceptor.LoggingInInterceptor" />  
  11.     <bean id="logOut" class="org.apache.cxf.interceptor.LoggingOutInterceptor" />  
  12.     <bean id="saajOut" class="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor" />  
  13.     <!-- <bean id="soapheaderOut" class="com.mms.client.writeSOAPHeaderInterceptor" /> -->  
  14.     <bean id="wss4jOut" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">  
  15.         <constructor-arg>  
  16.             <map>  
  17.                 <entry key="action" value="UsernameToken" />  
  18.                 <entry key="passwordType" value="PasswordText" />  
  19.                 <entry key="user" value="admin" />  
  20.                 <entry key="passwordCallbackClass" value="com.mms.client.ClientPasswordCallback" />  
  21.             </map>  
  22.         </constructor-arg>  
  23.     </bean>  
  24.     <!-- 客户端的配置 -->  
  25.     <jaxws:client id="client" serviceClass="com.mms.webservice.HelloWorld" address="http://127.0.0.1:8080/CXFSecurity/HelloWorld">  
  26.         <jaxws:inInterceptors>  
  27.             <ref bean="logIn" />  
  28.         </jaxws:inInterceptors>  
  29.         <jaxws:outInterceptors>  
  30.             <ref bean="logOut" />  
  31.             <ref bean="saajOut" />  
  32.             <!--<ref bean="soapheaderOut" /> -->  
  33.             <ref bean="wss4jOut" />  
  34.         </jaxws:outInterceptors>  
  35.     </jaxws:client>  
  36. </beans>  

服务器spring配置文件:server.xml

[html] view plaincopy
  1. <beans xmlns="http://www.springframework.org/schema/beans"  
  2.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws"  
  3.     xsi:schemaLocation="   
  4. http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd   
  5. http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">  
  6.     <!-- jar包中自带的cxf文件夹下的*.xml文件 -->  
  7.     <import resource="classpath:META-INF/cxf/cxf.xml" />  
  8.     <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />  
  9.     <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />  
  10.     <!-- 定义服务端的拦截器对象 -->  
  11.     <bean id="logIn" class="org.apache.cxf.interceptor.LoggingInInterceptor" />  
  12.     <bean id="logOut" class="org.apache.cxf.interceptor.LoggingOutInterceptor" />  
  13.     <bean id="saajIn" class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor" />  
  14.     <!-- <bean id="soapheaderIn" class="com.mms.webservice.test.readSOAPHeaderInterceptor" /> -->  
  15.     <bean id="wss4jIn" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">  
  16.         <constructor-arg>  
  17.             <map>  
  18.                 <entry key="action" value="UsernameToken" />  
  19.                 <entry key="passwordType" value="PasswordText" />  
  20.                 <entry key="passwordCallbackClass" value="com.mms.webservice.test.ServerPasswordCallback" />  
  21.             </map>  
  22.         </constructor-arg>  
  23.     </bean>  
  24.     <jaxws:endpoint id="helloWorld" implementor="com.mms.webservice.HelloWorldImpl"  
  25.         address="/HelloWorld">  
  26.         <jaxws:inInterceptors>  
  27.             <ref bean="logIn" />  
  28.             <ref bean="saajIn" />  
  29.             <!--<ref bean="soapheaderIn" /> -->  
  30.             <ref bean="wss4jIn" />  
  31.         </jaxws:inInterceptors>  
  32.         <jaxws:outInterceptors>  
  33.             <ref bean="logOut" />  
  34.         </jaxws:outInterceptors>  
  35.     </jaxws:endpoint>  
  36.   
  37. </beans>   

测试Client.java

[html] view plaincopy
  1. <pre class="java" name="code">package com.mms.client;  
  2. import org.springframework.context.ApplicationContext;  
  3. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  4. import com.mms.webservice.HelloWorld;  
  5.   
  6. public final class Client {  
  7.   
  8.     private Client() {  
  9.     }  
  10.   
  11.     public static void main(String args[]) throws Exception {  
  12.                 ApplicationContext  context = new ClassPathXmlApplicationContext(  
  13.                 new String[] { "client.xml" });  
  14.         HelloWorld client = (HelloWorld) context.getBean("client");  
  15.         String response = client.sayHi("hello test!");  
  16.         System.out.println("Response: " + response);  
  17.     }  
  18. }</pre>  
  19. <pre></pre>  
  20. <pre></pre>  
  21. <pre></pre>  
  22. <pre></pre>  
  23. <pre></pre>  
0 0