首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > Web前端 >

CXF Web Service 安全认证疏失?求大牛解决

2013-12-28 
CXF Web Service 安全认证出错?求大牛解决公司最近要采用CXF Web Service技术,本人写了个Demo,一路还都OK,

CXF Web Service 安全认证出错?求大牛解决
公司最近要采用CXF Web Service技术,本人写了个Demo,一路还都OK,但是就是在加入安全认证时出现问题,在百度、谷歌搜索了N久,参考修改了N久,还是解决不了,自己本人都解决吐了,现在求各位大神,大牛解决。
问题:(1)没有加入认证时,客户端连接请求成功!
      (2)加入安全认证后,出现bug,在eclipse和MyEclipse出现的报错信息还不一样。
一、服务器代码:
1、ServerPasswordCallbackHandler.java 安全拦截器

package com.credit56.demo.cxf.handler.soap;      import java.io.IOException;      import javax.security.auth.callback.Callback;  import javax.security.auth.callback.CallbackHandler;  import javax.security.auth.callback.UnsupportedCallbackException;      import org.apache.wss4j.common.ext.WSPasswordCallback;      /**  * <p + wsPasswordCallBack.getPassword());  if (USER.equals(wsPasswordCallBack.getIdentifier()) && PASSWORD.equals(wsPasswordCallBack.getPassword())) {  System.out.println("======= Successful ! =======");  } else {  // throw new WSSecurityException("No Permission!");  }  }      }  

2.IGreetingService 接口
package com.credit56.demo.cxf.service;      import javax.jws.WebMethod;  import javax.jws.WebParam;  import javax.jws.WebService;      import com.credit56.demo.cxf.model.Customer;      /**  *   * <p name="code">package com.credit56.demo.cxf.service.impl;      import java.text.SimpleDateFormat;  import java.util.Date;  import java.util.Set;      import javax.annotation.Resource;  import javax.xml.ws.WebServiceContext;  import javax.xml.ws.handler.MessageContext;      import net.sf.json.JSONObject;      import org.apache.cxf.interceptor.LoggingInInterceptor;  import org.apache.cxf.interceptor.LoggingOutInterceptor;  import org.apache.cxf.jaxws.JaxWsServerFactoryBean;          import com.credit56.demo.cxf.model.Customer;  import com.credit56.demo.cxf.service.IGreetingService;      /**  * <p + name);  return new StringBuffer(name).append(",Hello Word! currentTime is ").append(new Date()).toString();  }      /** *  * <p + messageContext.get(key));  /* * try { System.out.println("+++++++++scope:" + * messageContext.getScope(key)); } catch (Exception e) { * System.out.println("+++++++++++"+ key + "is not exits"); } */  }      if (null != customer.getId()) {  return customer;  }  Customer c = new Customer();  c.setId(1L);  c.setBirthday(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));  c.setName("shuqin_wang");  return c;  }      /** *  * <p name="code"><?xml version="1.0" encoding="UTF-8"?>  <beans xmlns="http://www.springframework.org/schema/beans"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"  xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:jaxrs="http://cxf.apache.org/jaxrs"  xsi:schemaLocation="         http://www.springframework.org/schema/beans         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd         http://www.springframework.org/schema/context         http://www.springframework.org/schema/context/spring-context-3.0.xsd         http://cxf.apache.org/jaxws          http://cxf.apache.org/schemas/jaxws.xsd    http://cxf.apache.org/jaxrs      http://cxf.apache.org/schemas/jaxrs.xsd">              <!-- Import Apache CXF Bean Definition -->  <import resource="classpath*:META-INF/cxf/cxf.xml" />  <import resource="classpath*:META-INF/cxf/cxf-extension-soap.xml" />  <import resource="classpath*:META-INF/cxf/cxf-servlet.xml" />      <bean id="wss4jInInterceptor" value="UsernameToken" />  <entry key="passwordType" value="PasswordText" />  <entry key="passwordCallbackClass"  value="com.credit56.demo.cxf.handler.soap.ServerPasswordCallbackHandler" />  </map>  </constructor-arg>  </bean>      <jaxws:endpoint id="greetingService"  implementor="com.credit56.demo.cxf.service.impl.GreetingServiceImpl"  address="/greetingService">  <jaxws:inInterceptors>  <ref bean="wss4jInInterceptor" />  </jaxws:inInterceptors>  </jaxws:endpoint>      <bean id="studentService" />  <jaxrs:server id="studentServiceWs" address="/studentService">  <jaxrs:serviceBeans>  <ref bean="studentService" />  </jaxrs:serviceBeans>  </jaxrs:server>      </beans>  


二、客户端:
1、客户端认证拦截器(out)
package com.credit56.demo.cxf.client.soap.handler;      import java.io.IOException;      import javax.security.auth.callback.Callback;  import javax.security.auth.callback.CallbackHandler;  import javax.security.auth.callback.UnsupportedCallbackException;      import org.apache.wss4j.common.ext.WSPasswordCallback;      /**  * <p name="code">package com.credit56.demo.cxf.client;      import java.text.SimpleDateFormat;  import java.util.Date;      import org.springframework.context.support.ClassPathXmlApplicationContext;      import com.credit56.demo.cxf.client.model.Customer;  import com.credit56.demo.cxf.client.service.IGreetingService;      //org/apache/xml/security/resource/xmlsecurity      import org.apache.xml.security.resource.schema.*;      public class CXFTest {      public static void main(String[] args) {      System.out.println("======"+ System.getProperty("java.endorsed.dirs"));  IGreetingService greetingServiceClient = (IGreetingService) new ClassPathXmlApplicationContext(  "classpath:applicationContext.xml").getBean("greetingServiceClient");  //greetingServiceClient.greeting("shuqin_wang");  Customer customer = new Customer();  customer.setId(1L);  customer.setBirthday(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));  customer.setName("hailong_qin");  Customer c = greetingServiceClient.getCustomer(customer);  System.out.println("id:" + c.getId() + "  name:" + c.getName() + "  birthday:" + c.getBirthday());  System.out.println(greetingServiceClient.getCustomerOfJSON());  }      }  

3、客户端 applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>  <beans xmlns="http://www.springframework.org/schema/beans"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"  xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:jaxrs="http://cxf.apache.org/jaxrs"  xsi:schemaLocation="         http://www.springframework.org/schema/beans         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd         http://www.springframework.org/schema/context         http://www.springframework.org/schema/context/spring-context-3.0.xsd         http://cxf.apache.org/jaxws          http://cxf.apache.org/schemas/jaxws.xsd    http://cxf.apache.org/jaxrs      http://cxf.apache.org/schemas/jaxrs.xsd">          <import resource="classpath*:META-INF/cxf/cxf.xml" />  <import resource="classpath*:META-INF/cxf/cxf-extension-soap.xml" />  <!-- <import resource="classpath*:META-INF/cxf/cxf-extension-jaxrs-binding.xml"   /> -->  <import resource="classpath*:META-INF/cxf/cxf-servlet.xml" />      <bean id="wss4jOutInterceptor" value="UsernameToken" />  <entry key="user" value="shuqin_wang" />  <entry key="passwordType" value="PasswordText" />  <entry key="passwordCallbackClass"  value="com.credit56.demo.cxf.client.soap.handler.ClientPasswordCallbackHandler" />  </map>  </constructor-arg>  </bean>      <!-- 通过与服务端配置相对的 CXF 标签 <jaxws:client> 来定义客户端访问服务的声明 -->  <jaxws:client id="greetingServiceClient"  service address="http://localhost:80/cxfdemo/greetingService">    <jaxws:outInterceptors>  <ref bean="wss4jOutInterceptor" />  </jaxws:outInterceptors>   </jaxws:client>      </beans>  


三、不同的开发环境报错信息居然不一样:
1、MyEclipse环境报错信息:
24 17:33:40 org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean buildServiceFromClass  信息: Creating Service {http://service.client.cxf.demo.credit56.com/}IGreetingServiceService from class com.credit56.demo.cxf.client.service.IGreetingService  Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'greetingServiceClient': FactoryBean threw exception on object creation; nested exception is java.lang.LinkageError: 正在从引导类加载器加载 JAXB 2.1 API, 但此 RI (来自jar:file:/F:/cxflib/apache-cxf-3.0.0-milestone1/lib/jaxb-impl-2.2.6.jar!/com/sun/xml/bind/v2/model/impl/ModelBuilder.class) 需要 2.2 API。请使用授权目录机制将 jaxb-api.jar 放在引导类加载器中。(请参阅 http://java.sun.com/j2se/1.6.0/docs/guide/standards/)  at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:149)  at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:102)  at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1468)  at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:249)  at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)  at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1117)  at com.credit56.demo.cxf.client.CXFTest.main(CXFTest.java:16)  Caused by: java.lang.LinkageError: 正在从引导类加载器加载 JAXB 2.1 API, 但此 RI (来自jar:file:/F:/cxflib/apache-cxf-3.0.0-milestone1/lib/jaxb-impl-2.2.6.jar!/com/sun/xml/bind/v2/model/impl/ModelBuilder.class) 需要 2.2 API。请使用授权目录机制将 jaxb-api.jar 放在引导类加载器中。(请参阅 http://java.sun.com/j2se/1.6.0/docs/guide/standards/)  at com.sun.xml.bind.v2.model.impl.ModelBuilder.<clinit>(ModelBuilder.java:178)  at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:455)  at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:303)  at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:142)  at com.sun.xml.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1174)  at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:162)  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)  at java.lang.reflect.Method.invoke(Method.java:597)  at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:210)  at javax.xml.bind.ContextFinder.find(ContextFinder.java:368)  at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:574)  at org.apache.cxf.common.jaxb.JAXBContextCache$2.run(JAXBContextCache.java:331)  at org.apache.cxf.common.jaxb.JAXBContextCache$2.run(JAXBContextCache.java:329)  at java.security.AccessController.doPrivileged(Native Method)  at org.apache.cxf.common.jaxb.JAXBContextCache.createContext(JAXBContextCache.java:329)  at org.apache.cxf.common.jaxb.JAXBContextCache.getCachedContextAndSchemas(JAXBContextCache.java:230)  at org.apache.cxf.jaxb.JAXBDataBinding.createJAXBContextAndSchemas(JAXBDataBinding.java:465)  at org.apache.cxf.jaxb.JAXBDataBinding.initialize(JAXBDataBinding.java:322)  at org.apache.cxf.service.factory.AbstractServiceFactoryBean.initializeDataBindings(AbstractServiceFactoryBean.java:86)  at org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean.buildServiceFromClass(ReflectionServiceFactoryBean.java:490)  at org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean.buildServiceFromClass(JaxWsServiceFactoryBean.java:704)  at org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean.initializeServiceModel(ReflectionServiceFactoryBean.java:550)  at org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean.create(ReflectionServiceFactoryBean.java:265)  at org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean.create(JaxWsServiceFactoryBean.java:215)  at org.apache.cxf.frontend.AbstractWSDLBasedEndpointFactory.createEndpoint(AbstractWSDLBasedEndpointFactory.java:102)  at org.apache.cxf.frontend.ClientFactoryBean.create(ClientFactoryBean.java:91)  at org.apache.cxf.frontend.ClientProxyFactoryBean.create(ClientProxyFactoryBean.java:157)  at org.apache.cxf.jaxws.JaxWsProxyFactoryBean.create(JaxWsProxyFactoryBean.java:142)  at org.apache.cxf.jaxws.spring.JaxWsProxyFactoryBeanDefinitionParser$JAXWSSpringClientProxyFactoryBean.create(JaxWsProxyFactoryBeanDefinitionParser.java:79)  at org.apache.cxf.jaxws.spring.JaxWsProxyFactoryBeanDefinitionParser$JAXWSSpringClientProxyFactoryBean.getObject(JaxWsProxyFactoryBeanDefinitionParser.java:83)  at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:142)  ... 6 more

2、Eclipse环境报错:
警告: Interceptor for {http://service.client.cxf.demo.credit56.com/}IGreetingServiceService#{http://service.client.cxf.demo.credit56.com/}getCustomer has thrown exception, unwinding now  java.util.MissingResourceException: Can't find bundle for base name org/apache/xml/security/resource/xmlsecurity, locale zh_CN  at java.util.ResourceBundle.throwMissingResourceException(ResourceBundle.java:1499)  at java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1322)  at java.util.ResourceBundle.getBundle(ResourceBundle.java:721)  at org.apache.wss4j.common.crypto.WSProviderConfig$4.<init>(WSProviderConfig.java:138)  at org.apache.wss4j.common.crypto.WSProviderConfig.initializeResourceBundles(WSProviderConfig.java:135)  at org.apache.wss4j.common.crypto.WSProviderConfig.init(WSProviderConfig.java:69)  at org.apache.wss4j.dom.WSSConfig.init(WSSConfig.java:387)  at org.apache.wss4j.dom.WSSConfig.getNewInstance(WSSConfig.java:394)  at org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor$WSS4JOutInterceptorInternal.handleMessage(WSS4JOutInterceptor.java:180)  at org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor$WSS4JOutInterceptorInternal.handleMessage(WSS4JOutInterceptor.java:140)  at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)  at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:502)  at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:411)  at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:314)  at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:267)  at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)  at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:137)  at com.sun.proxy.$Proxy39.getCustomer(Unknown Source)  at com.credit56.demo.cxf.client.CXFTest.main(CXFTest.java:28)      Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: Can't find bundle for base name org/apache/xml/security/resource/xmlsecurity, locale zh_CN  at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:159)  at com.sun.proxy.$Proxy39.getCustomer(Unknown Source)  at com.credit56.demo.cxf.client.CXFTest.main(CXFTest.java:28)  Caused by: java.util.MissingResourceException: Can't find bundle for base name org/apache/xml/security/resource/xmlsecurity, locale zh_CN  at java.util.ResourceBundle.throwMissingResourceException(ResourceBundle.java:1499)  at java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1322)  at java.util.ResourceBundle.getBundle(ResourceBundle.java:721)  at org.apache.wss4j.common.crypto.WSProviderConfig$4.<init>(WSProviderConfig.java:138)  at org.apache.wss4j.common.crypto.WSProviderConfig.initializeResourceBundles(WSProviderConfig.java:135)  at org.apache.wss4j.common.crypto.WSProviderConfig.init(WSProviderConfig.java:69)  at org.apache.wss4j.dom.WSSConfig.init(WSSConfig.java:387)  at org.apache.wss4j.dom.WSSConfig.getNewInstance(WSSConfig.java:394)  at org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor$WSS4JOutInterceptorInternal.handleMessage(WSS4JOutInterceptor.java:180)  at org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor$WSS4JOutInterceptorInternal.handleMessage(WSS4JOutInterceptor.java:140)  at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)  at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:502)  at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:411)  at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:314)  at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:267)  at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)  at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:137)  ... 2 more  

四、尝试过的方法:
1、找到相应位置,将apache-cxf-2.7.4\lib\endorsed下的jar文件放到对应目录下即可。如果没有endorsed目录,则手动建立该目录。
2、JDK升级到1.7
3、等等
五、附上源代码
1、cxfdemo.zip          ---服务端代码
2、csfdemoclient.zip    --- 客户端代码 1 楼 iuhoay 昨天   main 方法里 Spring 路径错了

热点排行