首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

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

2012-10-17 
CFX 和Spring 整合Ws Security 出现的问题?package com.easyway.cxf.securityimport java.io.IOException

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" />
? <bean id="logOut" />
? <bean id="saajIn" />
? <bean id="wss4jIn" value="UsernameToken"></entry>
??????<entry key="passwordType" value="PasswordText" />
??????<entry key="passwordCallbackClass" value="com.easyway.cxf.security.ServerPasswordHandler" />
?????</map>
?? </constructor-arg>
? </bean>???
?
?
? <bean id="helloServiceBean" 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" 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" />
? <bean id="logOut" />
? <bean id="saajOut" />
? <bean id="wss4jOut" 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" 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" 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

?

?

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

热点排行