`
longgangbai
  • 浏览: 7330303 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

CFX 和Spring 整合Ws Security 出现的问题?

阅读更多

package com.easyway.cxf.security;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;

import org.apache.ws.security.WSPasswordCallback;
/**
 * 采用回调方法检测WS调用的安全性
 * @author longgangbai
 *
 */
public class ServerPasswordHandler implements CallbackHandler{

 private Map<String, String> passwords;  
 
 public ServerPasswordHandler(){
  passwords=new HashMap<String, String>();
     passwords.put("admin", "admin");  
        passwords.put("test", "test");  
        passwords.put("userName", "password");
 }
 
 public void handle(Callback[] callbacks) throws IOException,
   UnsupportedCallbackException {
   WSPasswordCallback pc = (WSPasswordCallback) callbacks[0]; 
   //获取用户名
   String id = pc.getIdentifier();
   System.out.println("id==="+id);
   //获取密码
   String password = pc.getPassword(); 
      if(passwords.containsKey(id)){
       if(!password.equals(passwords.get(id))){
        throw new SecurityException("wrong password");
       }
      }else{
       throw new SecurityException("wrong username");
      }
 }
}
package com.easyway.cxf.security;

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.ws.security.WSPasswordCallback;

public class ClientPasswordCallback implements CallbackHandler {

  public void handle(Callback[] callbacks) throws IOException,
    UnsupportedCallbackException {
             WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];   
             int usage = pc.getUsage();   
             System.out.println("identifier: " + pc.getIdentifier());   
             System.out.println("usage: " + pc.getUsage());   
             if (usage == WSPasswordCallback.USERNAME_TOKEN) { 
              System.out.println("admin =====");
                     pc.setPassword("admin");  
                     pc.setIdentifier("admin");
             }
  }   

 }

package com.easyway.cxf.service;

import javax.jws.WebParam;
import javax.jws.WebService;
import java.util.List;


import com.easyway.cxf.model.User;
/**
 *
 * 采用JaxWS发布服务
 * 备注在接口中必须使用@WebService 注解否则出现错误
 *
 *
 * @author longgangbai
 *
 */
@WebService
public interface HelloService {
 /**
  * The @WebParam annotation is necessary as java interfaces do not store the Parameter name in the .class file. So if you leave out the annotation your parameter will be named arg0.
  * @param name
  * @return
  */
  public String hello(@WebParam(name="text")String name);
 
  /**
   * Advanced usecase of passing an Interface in.  JAX-WS/JAXB does not
   * support interfaces directly.  Special XmlAdapter classes need to
   * be written to handle them
   */
  public String sayHi(User user);

  public String[] getAllUseNames(List<User> userList);
}
package com.easyway.cxf.service;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.jws.WebService;

import com.easyway.cxf.model.User;
/**
 *
 *  采用JaxWS发布服务
 * 
 * JAX-WS includes many more annotations as well such as:
 *
 * @WebMethod - allows you to customize the operation name, exclude the operation from inclusion in the service, etc
 * @WebParam - allows you to customize a parameter's name, namespace, direction (IN or OUT), etc
 * @WebResult - allows you to customize the return value of the web service call
 *
 * @author longgangbai
 *
 */
@WebService(endpointInterface = "com.easyway.cxf.service.HelloService",
        serviceName = "HelloService")
public class HelloServiceImpl implements HelloService {

    Map<Integer, User> users = new LinkedHashMap<Integer, User>();
   

 public String hello(String username) {
        return "Hello " + username;
 }

 public String sayHi(User user) {
         users.put(users.size() + 1, user);
         return "Hello "  + user.getUsername();
 }
 public String[] getAllUseNames(List<User> userList) {
  String[] userListArr=new String[userList.size()];
  for (int i=0;i<userList.size();i++) {
   userListArr[i]=userList.get(i).getUsername();
  }
  return userListArr;
 }

}

 

采用如下代码测试没有问题:

package com.easyway.cxf.test.client.security;

import java.util.HashMap;
import java.util.Map;

import org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.handler.WSHandlerConstants;

import com.easyway.cxf.security.ClientPasswordCallback;
import com.easyway.cxf.service.HelloService;
import com.easyway.cxf.test.client.CFXClient;
/**
 *
 * @author Administrator
 *
 */
public class CXFClientSecurity {
public static void main(String[] args) {
 JaxWsProxyFactoryBean factory=new JaxWsProxyFactoryBean();
 Map<String, Object> outProps = new HashMap<String, Object>();
 outProps.put(WSHandlerConstants.ACTION,WSHandlerConstants.USERNAME_TOKEN);
 outProps.put(WSHandlerConstants.USER, "userName");
 outProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);
 outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS,
 ClientPasswordCallback.class.getName());
 WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps);
 factory.getOutInterceptors().add(wssOut);
 factory.getOutInterceptors().add(new SAAJOutInterceptor());
 factory.setServiceClass(HelloService.class);
 //和服务端发送路径一样的
 factory.setAddress(CFXClient.SERVICE_ADDRESS);
 HelloService helloService=(HelloService)factory.create();
 String msg=helloService.hello("xiaobai");
 System.out.println("msg="+msg);
}
}
package com.easyway.cxf.test.client.security;

import java.util.HashMap;
import java.util.Map;

import org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.handler.WSHandlerConstants;

import com.easyway.cxf.security.ClientPasswordCallback;
import com.easyway.cxf.service.HelloService;
import com.easyway.cxf.test.client.CFXClient;
/**
 *
 * @author Administrator
 *
 */
public class CXFClientSecurity {
public static void main(String[] args) {
 JaxWsProxyFactoryBean factory=new JaxWsProxyFactoryBean();
 Map<String, Object> outProps = new HashMap<String, Object>();
 outProps.put(WSHandlerConstants.ACTION,WSHandlerConstants.USERNAME_TOKEN);
 outProps.put(WSHandlerConstants.USER, "userName");
 outProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);
 outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS,
 ClientPasswordCallback.class.getName());
 WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps);
 factory.getOutInterceptors().add(wssOut);
 factory.getOutInterceptors().add(new SAAJOutInterceptor());
 factory.setServiceClass(HelloService.class);
 //和服务端发送路径一样的
 factory.setAddress(CFXClient.SERVICE_ADDRESS);
 HelloService helloService=(HelloService)factory.create();
 String msg=helloService.hello("xiaobai");
 System.out.println("msg="+msg);
}
}
采用Spring applicationContext-server.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:jaxws="http://cxf.apache.org/jaxws"
                 xsi:schemaLocation="
                       http://www.springframework.org/schema/beans
                       http://www.springframework.org/schema/beans/spring-beans.xsd
                       http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
    <!--
       服务端定义
       
       访问路径如下:http://localhost:8080/cxf/services/helloService?wsdl
       services:web.xml中配置的拦截路径
       /helloService:为服务的上下文
     -->              
 <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="logIn" class="org.apache.cxf.interceptor.LoggingInInterceptor" />
  <bean id="logOut" class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
  <bean id="saajIn" class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor" />
  <bean id="wss4jIn" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
      <constructor-arg>
     <map>
      <entry key="action" value="UsernameToken"></entry>
      <entry key="passwordType" value="PasswordText" />
      <entry key="passwordCallbackClass" value="com.easyway.cxf.security.ServerPasswordHandler" />
     </map>
   </constructor-arg>
  </bean>   
 
 
  <bean id="helloServiceBean" class="com.easyway.cxf.service.HelloServiceImpl"></bean>
   <!--
       服务端的配置
  -->
<bean id="proxyFactory" class="org.apache.cxf.jaxws.JaxWsServerFactoryBean">
    <property name="serviceBean">
        <ref bean="helloServiceBean"/>
    </property>
    <property name="address" value="http://localhost:8080/HelloService"/>
   
    <property name="inInterceptors">
      <list>
        <ref bean="logIn" />
         <ref bean="saajIn" />
        <ref bean="wss4jIn" />
      </list>
    </property>
   
    <property name="outInterceptors">
      <list>
        <ref bean="logOut" />
      </list>
    </property>
  </bean>
 
 <!--
   WS相关的服务
  -->
<bean id="server" class="org.apache.cxf.jaxws.JaxWsServerFactoryBean" factory-bean="proxyFactory"  factory-method="create" />

</beans>

 

client:applicationContext-client.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:jaxws="http://cxf.apache.org/jaxws"
                 xsi:schemaLocation="
                       http://www.springframework.org/schema/beans
                       http://www.springframework.org/schema/beans/spring-beans.xsd
                       http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
 
  <!--
 
  定义客户端的拦截器对象
   -->
  <bean id="logIn" class="org.apache.cxf.interceptor.LoggingInInterceptor" />
  <bean id="logOut" class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
  <bean id="saajOut" class="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor" />
  <bean id="wss4jOut" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
    <constructor-arg>
      <map>
        <entry key="action" value="UsernameToken" />
        <entry key="user" value="ws-client" />
        <entry key="passwordType" value="PasswordText" />
        <entry key="passwordCallbackClass" value="com.easyway.cxf.security.ClientPasswordCallback" />
      </map>
    </constructor-arg>
  </bean>   
 
   <!--
       客户端的配置
  -->
<bean id="proxyFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
    <property name="serviceClass" value="com.easyway.cxf.service.HelloService"/>
    <property name="address" value="http://localhost:8080/HelloService"/>
    <property name="inInterceptors">
      <list>
        <ref bean="logIn" />
      </list>
    </property>
    <!-- 
    <property name="outInterceptors">
      <list>
        <ref bean="logOut" />
        <ref bean="saajOut" />
        <ref bean="wss4jOut" />
      </list>
    </property>
  -->
  </bean>
<!--
客户端使用的服务工厂
 -->
<bean id="client" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean" factory-bean="proxyFactory" factory-method="create" />

</beans>

测试代码;
package com.easyway.cxf.test.server;

import org.apache.cxf.endpoint.Server;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
 * Spring 和CXF 整合客户端 测试
 * @author longgangbai
 *
 */
public class SpringCXFServer {
 
 public static void main(String[] args) {
    Thread wsPublisher = new Thread(new WebServicePublish());
    wsPublisher.start();
   }

   private static class WebServicePublish implements Runnable {
    public void run() {

     ApplicationContext ctx=new ClassPathXmlApplicationContext("/applicationContext-server.xml");
    
     Server client = (Server)ctx.getBean("server");
     client.start();
    }
   }

}
package com.easyway.cxf.test.client;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.easyway.cxf.model.User;
import com.easyway.cxf.service.HelloService;
/**
 * Spring 和CXF 整合客户端 测试
 * @author longgangbai
 *
 */


public class SpringCXFClient {
 
 public static void main(String[] args) {
    ApplicationContext ctx=new ClassPathXmlApplicationContext("/applicationContext-client.xml");
   
    HelloService client = (HelloService)ctx.getBean("client");
   
          User user=new User();
          user.setPassword("password");
          user.setUsername("username");
          System.out.println(client.sayHi(user));
  
  
 }

}
客户端正常,服务端报错:

------------------------------------
Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: An error was discovered processing the <wsse:Security> header
 at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:147)
 at $Proxy45.sayHi(Unknown Source)
 at com.easyway.cxf.test.client.SpringCXFClient.main(SpringCXFClient.java:25)
Caused by: org.apache.cxf.binding.soap.SoapFault: An error was discovered processing the <wsse:Security> header

 

 

分享到:
评论
3 楼 jiangli19192 2012-09-04  
我也是这个问题,你解决没有?
2 楼 ljz0898 2011-07-05  
我也报这个错误 解决了很长时间还是没搞定 麻烦告诉我一下你是怎么解决的 好吗?谢谢
1 楼 luohong0327 2011-04-18  
我也报这个错,有解决办法了吗?

相关推荐

    CXF和Spring整合开发的服务端及客户端

    【CXF和Spring整合开发的服务端及客户端】 CXF(CXF: Composite eXtensible Services Framework)是一款开源的Java框架,主要用于构建和开发服务导向架构(SOA)中的Web服务。它支持多种协议和标准,如SOAP、...

    Spring整合CXF步骤,Spring实现webService,spring整合WebService

    Spring和CXF还支持对Web服务异常的处理以及安全性的配置,比如WS-Security。你可以通过Spring的AOP(面向切面编程)来定义全局的异常处理器,或者在`jaxws:endpoint`中配置安全性相关的属性。 8. **源码和工具的...

    cxf+spring的webservice实例

    - 利用CXF的WS-Security等高级功能,确保服务的安全性。 总的来说,"cxf+spring的webservice实例"是一个实践性的教程,旨在帮助开发者理解如何在Spring环境中利用CXF快速构建和部署Web服务。通过这个实例,你可以...

    webservice的cfx框架

    它还支持WS-Security(Web Services Security)标准,可以实现消息级别的安全性,如签名、加密和令牌验证。 5. 插件和扩展:CXF有丰富的插件和扩展库,支持诸如MTOM(Message Transmission Optimization Mechanism...

    cfx的jar包

    “webservice”标签表示这是一个与Web服务相关的技术,CXF是Java中实现Web服务的一个重要工具,它支持各种Web服务标准,包括WSDL(Web Services Description Language)、SOAP、WS-Security等。 “cxf”标签直接...

    WebService详细解析(axis,xfire,cxf,授权认证加密解密)

    CXF是Apache基金会的一个项目,它整合了XFire和Axis2的优势,提供了一站式的解决方案,支持SOAP、REST、WS-*标准等。 4. CXF特性 - 强大的工具集,包括WSDL-to-Java和Java-to-WSDL工具。 - 对WS-Security、WS-...

    cxf+spring webService实例

    Spring的Web服务模块(Spring-WS)提供了基于契约优先的Web服务开发方式,而CXF与Spring的集成则可以让开发者利用Spring的丰富特性来管理和配置Web服务。 在"CXF+Spring WebService实例"中,我们需要完成以下步骤:...

    cxf与axis2区别

    CXF支持WS-Addressing、WS-Policy、WS-RM、WS-Security和WS-I BasicProfile等webservices标准,Axis2支持WS-Addressing、WS-RM、WS-Security和WS-I BasicProfile,WS-Policy将在新版本中得到支持。 CXF的标准支持...

    Axis和CXF的比较

    - **CXF 2.0及以上版本**:提供了强大的功能集,包括对最新Web服务规范的支持,如WS-Addressing、WS-Policy、WS-RM、WS-Security等。 #### 四、Axis与CXF的主要区别 1. **对Web服务标准的支持**: - **Axis2**:...

    web service开发 cxf框架帮助文档

    5. **丰富的功能**:支持MTOM(Message Transmission Optimization Mechanism)、SwA(SwA Attachments,用于传递二进制附件)、WS-Security等高级特性。 **CXF文档资源** 帮助文档是学习和使用CXF的关键。CXF的...

    cxf 源码 java websevice

    4. **WS-*支持**:CXF实现了WS-Security、WS-ReliableMessaging、WS-Addressing等WS-*家族的标准,为Web服务提供了安全、可靠性和管理性。 5. **互操作性**:CXF的强项之一是其良好的互操作性,它可以与其他Web服务...

    cxfService

    - `cxf-rt-ws-security` - `cxf-rt-core` 三、定义 Web 服务接口 1. **接口定义**:使用 `@WebService` 注解定义一个 Web 服务接口,例如: ```java package demo; import javax.jws.WebService; @...

Global site tag (gtag.js) - Google Analytics