cxf ws_security

来源:互联网 发布:wordpress 开发 知乎 编辑:程序博客网 时间:2024/05/22 08:22
CXF的webService已经创建好,但没有安全可言,毕竟这是Internet服务呀。
CXF给了一个很完整的安全架构,但CXF给出的ws_security DEMO太复杂了,又是password jks X509 Timestamp。 我试了很多次都没有成功。化繁为简,只实现一个user password好了。其实CXF和Spring——ACEGI的认证机制很像的都是使用了intercetor。
下面开始
编写cxf.xml在原来的bean的地方声明一下就可以了
Java代码
  1.     <bean id="WSS4JInInterceptor" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">   
  2.         <constructor-arg>   
  3.             <map>   
  4.                 <entry key="action" value="UsernameToken" />   
  5.                 <entry key="passwordType" value="PasswordText" />   
  6.                 <entry key="passwordCallbackClass"  
  7.                     value="com.mms.webservice.test.ServerPasswordCallback" />  
  8.                 <!--
  9.                    这里和上面的passwordCallbackClass效果一样,只不过是引用一个受管Bean,注入资源     
  10.                   <entry key="passwordCallbackRef">
                        <ref bean="serverPasswordCallback"/>
                      </entry>    

  11.                   在外面的位置可以继续添加

  12.                   <bean id="serverPasswordCallback"                                                                          adclass="cn.sz_sunshine.envinspector.security.ServerPasswordCallback">
                           <property name="userManager">
                              <ref bean="UserManager" />
                           </property>
                      </bean>  
  13.                 -->
  14.             </map>   
  15.         </constructor-arg>   
  16.     </bean>   
  17.   
  18. <jaxws:endpoint id="helloWorld"  
  19.         implementor="com.mms.webservice.HelloWorldImpl"  
  20.         address="/HelloWorld">   
  21.         <jaxws:inInterceptors>   
  22.         <!--    
  23.             <bean   
  24.                 class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor" />   
  25.             <bean   
  26.                 class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">   
  27.                 <constructor-arg>   
  28.                     <map>   
  29.                         <entry key="action" value="UsernameToken" />   
  30.                         <entry key="passwordType" value="PasswordText" />   
  31.                         <entry key="passwordCallbackClass"  
  32.                             value="com.mms.webservice.test.ServerPasswordCallback" />   
  33.                     </map>   
  34.                 </constructor-arg>   
  35.             </bean>   
  36.              -->   
  37.              <ref bean="WSS4JInInterceptor" />   
  38.         </jaxws:inInterceptors>   
  39.     </jaxws:endpoint>  
[java] view plaincopyprint?
  1.     <bean id="WSS4JInInterceptor" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">  
  2.         <constructor-arg>  
  3.             <map>  
  4.                 <entry key="action" value="UsernameToken" />  
  5.                 <entry key="passwordType" value="PasswordText" />  
  6.                 <entry key="passwordCallbackClass"  
  7.                     value="com.mms.webservice.test.ServerPasswordCallback" />  
  8.             </map>  
  9.         </constructor-arg>  
  10.     </bean>  
  11.   
  12. <jaxws:endpoint id="helloWorld"  
  13.         implementor="com.mms.webservice.HelloWorldImpl"  
  14.         address="/HelloWorld">  
  15.         <jaxws:inInterceptors>  
  16.         <!--   
  17.             <bean  
  18.                 class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor" />  
  19.             <bean  
  20.                 class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">  
  21.                 <constructor-arg>  
  22.                     <map>  
  23.                         <entry key="action" value="UsernameToken" />  
  24.                         <entry key="passwordType" value="PasswordText" />  
  25.                         <entry key="passwordCallbackClass"  
  26.                             value="com.mms.webservice.test.ServerPasswordCallback" />  
  27.                     </map>  
  28.                 </constructor-arg>  
  29.             </bean>  
  30.              -->  
  31.              <ref bean="WSS4JInInterceptor" />  
  32.         </jaxws:inInterceptors>  
  33.     </jaxws:endpoint>  

WSS4JInInterceptor就是我们要定义的东东了。CXf已经帮你写好了。设置属性就可以了。里面属性值挺多的,CXF的文档就是太简单了,opensource的弊病!属性值就查API吧。
下面需要写server端的密码回调函数,验证logic就在这里定义了。
Java代码 复制代码
  1. package com.mms.webservice.test;   
  2.   
  3. import java.io.IOException;   
  4. import java.util.ResourceBundle;   
  5.   
  6. import javax.security.auth.callback.Callback;   
  7. import javax.security.auth.callback.CallbackHandler;   
  8. import javax.security.auth.callback.UnsupportedCallbackException;   
  9.   
  10. import org.apache.ws.security.WSPasswordCallback;   
  11.   
  12. public class ServerPasswordCallback implements CallbackHandler {   
  13.   
  14.     private static final String BUNDLE_LOCATION = "com.mms.webservice.test.pass";   
  15.     private static final String PASSWORD_PROPERTY_NAME = "auth.manager.password";   
  16.   
  17.     private static String password;   
  18.     static {   
  19.         final ResourceBundle bundle = ResourceBundle.getBundle(BUNDLE_LOCATION);   
  20.         password = bundle.getString(PASSWORD_PROPERTY_NAME);   
  21.     }   
  22.   
  23.     public void handle(Callback[] callbacks) throws IOException,   
  24.             UnsupportedCallbackException {   
  25.   
  26.         WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];   
  27.   
  28.         // Set the password on the callback. This will be compared to the  
  29.         // password which was sent from the client.  
  30.         // We can call pc.getIdentifer() right here to check the username  
  31.         // if we want each client to have it's own password.  
  32.         if (pc.getIdentifer().equalsIgnoreCase("eric")) {   
  33.             if (!pc.getPassword().equals(password)) {   
  34.                 throw new SecurityException("wrong password");   
  35.             }   
  36.         }   
  37.         else  
  38.         {   
  39.             throw new SecurityException("the user does not exits");   
  40.         }   
  41.   
  42.     }   
  43.   
  44. }  
[java] view plaincopyprint?
  1. package com.mms.webservice.test;  
  2.   
  3. import java.io.IOException;  
  4. import java.util.ResourceBundle;  
  5.   
  6. import javax.security.auth.callback.Callback;  
  7. import javax.security.auth.callback.CallbackHandler;  
  8. import javax.security.auth.callback.UnsupportedCallbackException;  
  9.   
  10. import org.apache.ws.security.WSPasswordCallback;  
  11.   
  12. public class ServerPasswordCallback implements CallbackHandler {  
  13.   
  14.     private static final String BUNDLE_LOCATION = "com.mms.webservice.test.pass";  
  15.     private static final String PASSWORD_PROPERTY_NAME = "auth.manager.password";  
  16.   
  17.     private static String password;  
  18.     static {  
  19.         final ResourceBundle bundle = ResourceBundle.getBundle(BUNDLE_LOCATION);  
  20.         password = bundle.getString(PASSWORD_PROPERTY_NAME);  
  21.     }  
  22.   
  23.     public void handle(Callback[] callbacks) throws IOException,  
  24.             UnsupportedCallbackException {  
  25.   
  26.         WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];  
  27.   
  28.         // Set the password on the callback. This will be compared to the  
  29.         // password which was sent from the client.  
  30.         // We can call pc.getIdentifer() right here to check the username  
  31.         // if we want each client to have it's own password.  
  32.         if (pc.getIdentifer().equalsIgnoreCase("eric")) {  
  33.             if (!pc.getPassword().equals(password)) {  
  34.                 throw new SecurityException("wrong password");  
  35.             }  
  36.         }  
  37.         else  
  38.         {  
  39.             throw new SecurityException("the user does not exits");  
  40.         }  
  41.   
  42.     }  
  43.   
  44. }  

就此server端的验证就全部ok了。这时再调用原来的调用程序就会报ws_security错误了。

下面给出Client验证程序
其实就是在soapheader上加相应内容。也需要用到inInterceptors
Java代码 复制代码
  1. /**  
  2.  * Licensed to the Apache Software Foundation (ASF) under one 
  3.  * or more contributor license agreements. See the NOTICE file 
  4.  * distributed with this work for additional information 
  5.  * regarding copyright ownership. The ASF licenses this file 
  6.  * to you under the Apache License, Version 2.0 (the 
  7.  * "License"); you may not use this file except in compliance 
  8.  * with the License. You may obtain a copy of the License at 
  9.  *  
  10.  * http://www.apache.org/licenses/LICENSE-2.0 
  11.  *  
  12.  * Unless required by applicable law or agreed to in writing, 
  13.  * software distributed under the License is distributed on an 
  14.  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
  15.  * KIND, either express or implied. See the License for the 
  16.  * specific language governing permissions and limitations 
  17.  * under the License. 
  18.  */  
  19. package com.tnt.mms.webservice.client;   
  20.   
  21. import java.util.List;   
  22.   
  23. import org.springframework.context.support.ClassPathXmlApplicationContext;   
  24.   
  25. import com.tnt.mms.webservice.VendorMaintenance;   
  26. import com.tnt.mrm.model.other.Vendor;   
  27.   
  28. public final class ClientVendor {   
  29.   
  30.     private ClientVendor() {   
  31.     }   
  32.   
  33.     public static void main(String args[]) throws Exception {   
  34.         // START SNIPPET: client  
  35.         ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(   
  36.                 new String[] { "com/tnt/mms/webservice/client/client-vendor-beans.xml" });   
  37.   
  38.         try {   
  39.   
  40.             VendorMaintenance client = (VendorMaintenance) context   
  41.                     .getBean("client");   
  42.   
  43.             Vendor ls = client.get("10116");   
  44.             System.out.println("Response: " + ls.getEngName());   
  45.   
  46.             List<Vendor> rs = client.getList();   
  47.             System.out.println("Response: " + rs.size());   
  48.             System.out.println("Response: " + rs.get(0).getEngName());   
  49.   
  50.             System.exit(0);   
  51.   
  52.         } catch (Exception e) {   
  53.   
  54.             e.printStackTrace();   
  55.             System.out.println("error" + e.getMessage());   
  56.   
  57.         }   
  58.     }   
  59. }  
[java] view plaincopyprint?
  1. /** 
  2.  * Licensed to the Apache Software Foundation (ASF) under one 
  3.  * or more contributor license agreements. See the NOTICE file 
  4.  * distributed with this work for additional information 
  5.  * regarding copyright ownership. The ASF licenses this file 
  6.  * to you under the Apache License, Version 2.0 (the 
  7.  * "License"); you may not use this file except in compliance 
  8.  * with the License. You may obtain a copy of the License at 
  9.  * 
  10.  * http://www.apache.org/licenses/LICENSE-2.0 
  11.  * 
  12.  * Unless required by applicable law or agreed to in writing, 
  13.  * software distributed under the License is distributed on an 
  14.  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
  15.  * KIND, either express or implied. See the License for the 
  16.  * specific language governing permissions and limitations 
  17.  * under the License. 
  18.  */  
  19. package com.tnt.mms.webservice.client;  
  20.   
  21. import java.util.List;  
  22.   
  23. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  24.   
  25. import com.tnt.mms.webservice.VendorMaintenance;  
  26. import com.tnt.mrm.model.other.Vendor;  
  27.   
  28. public final class ClientVendor {  
  29.   
  30.     private ClientVendor() {  
  31.     }  
  32.   
  33.     public static void main(String args[]) throws Exception {  
  34.         // START SNIPPET: client  
  35.         ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(  
  36.                 new String[] { "com/tnt/mms/webservice/client/client-vendor-beans.xml" });  
  37.   
  38.         try {  
  39.   
  40.             VendorMaintenance client = (VendorMaintenance) context  
  41.                     .getBean("client");  
  42.   
  43.             Vendor ls = client.get("10116");  
  44.             System.out.println("Response: " + ls.getEngName());  
  45.   
  46.             List<Vendor> rs = client.getList();  
  47.             System.out.println("Response: " + rs.size());  
  48.             System.out.println("Response: " + rs.get(0).getEngName());  
  49.   
  50.             System.exit(0);  
  51.   
  52.         } catch (Exception e) {  
  53.   
  54.             e.printStackTrace();  
  55.             System.out.println("error" + e.getMessage());  
  56.   
  57.         }  
  58.     }  
  59. }  


client_vendor_beans.xml
Java代码 复制代码
  1. <?xml version="1.0" encoding="UTF-8"?>   
  2. <!--   
  3.     Licensed to the Apache Software Foundation (ASF) under one   
  4.     or more contributor license agreements. See the NOTICE file   
  5.     distributed with this work for additional information   
  6.     regarding copyright ownership. The ASF licenses this file   
  7.     to you under the Apache License, Version 2.0 (the   
  8.     "License"); you may not use this file except in compliance   
  9.     with the License. You may obtain a copy of the License at   
  10.        
  11.     http://www.apache.org/licenses/LICENSE-2.0  
  12.        
  13.     Unless required by applicable law or agreed to in writing,   
  14.     software distributed under the License is distributed on an   
  15.     "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY   
  16.     KIND, either express or implied. See the License for the   
  17.     specific language governing permissions and limitations   
  18.     under the License.   
  19. -->   
  20. <!-- START SNIPPET: beans -->   
  21. <beans xmlns="http://www.springframework.org/schema/beans"  
  22.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  23.     xmlns:jaxws="http://cxf.apache.org/jaxws"  
  24.     xsi:schemaLocation="   
  25. http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd  
  26. http://cxf.apache.org/jaxws http://cxf.apache.org/schema/jaxws.xsd">  
  27.     <!-- Configure CXF to use Aegis data binding instead of JAXB -->   
  28.     <bean id="aegisBean"  
  29.         class="org.apache.cxf.aegis.databinding.AegisDatabinding"  
  30.         scope="prototype" />   
  31.     <bean id="jaxwsAndAegisServiceFactory"  
  32.         class="org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean"  
  33.         scope="prototype">   
  34.         <property name="dataBinding" ref="aegisBean" />   
  35.         <property name="serviceConfigurations">   
  36.             <list>   
  37.                 <bean   
  38.                     class="org.apache.cxf.jaxws.support.JaxWsServiceConfiguration" />   
  39.                 <bean   
  40.                     class="org.apache.cxf.aegis.databinding.AegisServiceConfiguration" />   
  41.                 <bean   
  42.                     class="org.apache.cxf.service.factory.DefaultServiceConfiguration" />   
  43.             </list>   
  44.         </property>   
  45.     </bean>   
  46.   
  47.     <bean id="client" class="com.mms.webservice.VendorMaintenance"  
  48.         factory-bean="clientFactory" factory-method="create" />   
  49.   
  50.     <bean id="clientFactory"  
  51.         class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">   
  52.         <property name="serviceClass"  
  53.             value="com.mms.webservice.VendorMaintenance" />   
  54.         <property name="address"  
  55.             value="http://localhost:8080/extjsmms/services/VendorMaintenance" />   
  56.         <!--     <property name="serviceFactory" ref="jaxwsAndAegisServiceFactory"/> -->   
  57.         <property name="inInterceptors">   
  58.             <list>   
  59.                 <ref bean="logIn" />   
  60.             </list>   
  61.         </property>   
  62.         <property name="outInterceptors">   
  63.             <list>   
  64.                 <ref bean="logOut" />   
  65.                 <ref bean="saajOut" />   
  66.                 <ref bean="wss4jOut" />   
  67.             </list>   
  68.         </property>   
  69.     </bean>   
  70.   
  71.   
  72.     <bean id="logIn"  
  73.         class="org.apache.cxf.interceptor.LoggingInInterceptor" />   
  74.     <bean id="logOut"  
  75.         class="org.apache.cxf.interceptor.LoggingOutInterceptor" />   
  76.     <bean id="saajOut"  
  77.         class="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor" />   
  78.     <bean id="wss4jOut"  
  79.         class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">   
  80.         <constructor-arg>   
  81.             <map>   
  82.                 <entry key="action" value="UsernameToken" />   
  83.                 <entry key="user" value="eric" />   
  84.                 <entry key="passwordType" value="PasswordText" />   
  85.                 <entry key="passwordCallbackClass"  
  86.                     value="com.mms.webservice.client.ClientPasswordCallback" />   
  87.             </map>   
  88.         </constructor-arg>   
  89.     </bean>   
  90. </beans>   
  91. <!-- END SNIPPET: beans -->  
[java] view plaincopyprint?
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!--  
  3.     Licensed to the Apache Software Foundation (ASF) under one  
  4.     or more contributor license agreements. See the NOTICE file  
  5.     distributed with this work for additional information  
  6.     regarding copyright ownership. The ASF licenses this file  
  7.     to you under the Apache License, Version 2.0 (the  
  8.     "License"); you may not use this file except in compliance  
  9.     with the License. You may obtain a copy of the License at  
  10.       
  11.     http://www.apache.org/licenses/LICENSE-2.0  
  12.       
  13.     Unless required by applicable law or agreed to in writing,  
  14.     software distributed under the License is distributed on an  
  15.     "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY  
  16.     KIND, either express or implied. See the License for the  
  17.     specific language governing permissions and limitations  
  18.     under the License.  
  19. -->  
  20. <!-- START SNIPPET: beans -->  
  21. <beans xmlns="http://www.springframework.org/schema/beans"  
  22.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  23.     xmlns:jaxws="http://cxf.apache.org/jaxws"  
  24.     xsi:schemaLocation="  
  25. http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd  
  26. http://cxf.apache.org/jaxws http://cxf.apache.org/schema/jaxws.xsd">  
  27.     <!-- Configure CXF to use Aegis data binding instead of JAXB -->  
  28.     <bean id="aegisBean"  
  29.         class="org.apache.cxf.aegis.databinding.AegisDatabinding"  
  30.         scope="prototype" />  
  31.     <bean id="jaxwsAndAegisServiceFactory"  
  32.         class="org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean"  
  33.         scope="prototype">  
  34.         <property name="dataBinding" ref="aegisBean" />  
  35.         <property name="serviceConfigurations">  
  36.             <list>  
  37.                 <bean  
  38.                     class="org.apache.cxf.jaxws.support.JaxWsServiceConfiguration" />  
  39.                 <bean  
  40.                     class="org.apache.cxf.aegis.databinding.AegisServiceConfiguration" />  
  41.                 <bean  
  42.                     class="org.apache.cxf.service.factory.DefaultServiceConfiguration" />  
  43.             </list>  
  44.         </property>  
  45.     </bean>  
  46.   
  47.     <bean id="client" class="com.mms.webservice.VendorMaintenance"  
  48.         factory-bean="clientFactory" factory-method="create" />  
  49.   
  50.     <bean id="clientFactory"  
  51.         class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">  
  52.         <property name="serviceClass"  
  53.             value="com.mms.webservice.VendorMaintenance" />  
  54.         <property name="address"  
  55.             value="http://localhost:8080/extjsmms/services/VendorMaintenance" />  
  56.         <!--     <property name="serviceFactory" ref="jaxwsAndAegisServiceFactory"/> -->  
  57.         <property name="inInterceptors">  
  58.             <list>  
  59.                 <ref bean="logIn" />  
  60.             </list>  
  61.         </property>  
  62.         <property name="outInterceptors">  
  63.             <list>  
  64.                 <ref bean="logOut" />  
  65.                 <ref bean="saajOut" />  
  66.                 <ref bean="wss4jOut" />  
  67.             </list>  
  68.         </property>  
  69.     </bean>  
  70.   
  71.   
  72.     <bean id="logIn"  
  73.         class="org.apache.cxf.interceptor.LoggingInInterceptor" />  
  74.     <bean id="logOut"  
  75.         class="org.apache.cxf.interceptor.LoggingOutInterceptor" />  
  76.     <bean id="saajOut"  
  77.         class="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor" />  
  78.     <bean id="wss4jOut"  
  79.         class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">  
  80.         <constructor-arg>  
  81.             <map>  
  82.                 <entry key="action" value="UsernameToken" />  
  83.                 <entry key="user" value="eric" />  
  84.                 <entry key="passwordType" value="PasswordText" />  
  85.                 <entry key="passwordCallbackClass"  
  86.                     value="com.mms.webservice.client.ClientPasswordCallback" />  
  87.             </map>  
  88.         </constructor-arg>  
  89.     </bean>  
  90. </beans>  
  91. <!-- END SNIPPET: beans -->  

至此验证成功。


在我的资源中有一个关于这方面的demo,有需要的朋友可以去下来学习一下
地址:http://blog.csdn.net/cocojiji5/article/details/3564440
原创粉丝点击