论坛首页 Java企业应用论坛

CXF 密码权限控制 SOAP报头处理

浏览 12013 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2010-06-01  
SOA

前一段时间写了一篇CXF密码验证_服务端和客户端配置

 

当时没有系统的讲解:

个人认为CXF认证方式很多.一种就像上一篇文章写的是直接对传送的数据包进行密码封装!

另一种就是现在要介绍的是另外一种.对SOAP头处理..把需要验证的密码封装在SOAP头里传送!

可能表达不是很清楚..看代码吧:

1:服务端spring里的配置:

  <bean id="Customer" class="org.web.HelloServiceImpl"></bean>
	<jaxws:endpoint  id="custom"  implementor="#Customer"   address="/web" >
	  	 <jaxws:inInterceptors>  
            <bean class="org.apache.cxf.interceptor.LoggingInInterceptor" />  
            <!--<bean class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor" />  
            -->
            <bean class="org.web.soapHeader.ReadSoapHeader"></bean>
            <!--<bean class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">  
                <constructor-arg>  
                    <map>  
                        <entry key="action" value="UsernameToken" />  
                        <entry key="passwordType"  
                            value="PasswordText" />  
                        <entry key="user" value="cxfServer" />  
                        <entry key="passwordCallbackRef">  
                            <ref bean="serverPasswordCallback" />  
                        </entry>  
                    </map>  
                </constructor-arg>  
            </bean> -->
            </jaxws:inInterceptors>  
	 </jaxws:endpoint>

这个里面是有注释的..区别上一个密码验证的示例!

关键代码就有一句: <bean class="org.web.soapHeader.ReadSoapHeader"></bean>

  这个是自己写的读取soap信息.查看密码是否正确!

2:soap读入信息的验证:ReadSoapHeader代码:

public class ReadSoapHeader extends AbstractPhaseInterceptor<SoapMessage> {
	private SAAJInInterceptor saa=new SAAJInInterceptor();
	public ReadSoapHeader(){
		super(Phase.PRE_PROTOCOL);
		getAfter().add(SAAJInInterceptor.class.getName());
	}
	public void handleMessage(SoapMessage message) throws Fault {
		SOAPMessage mess=message.getContent(SOAPMessage.class);
		if(mess==null){
			saa.handleMessage(message);
			mess=message.getContent(SOAPMessage.class);
		}
		SOAPHeader head=null;
		try {
			head = mess.getSOAPHeader();
		} catch (SOAPException e) {
			e.printStackTrace();
		}
		if(head==null){
			return;
		}
		NodeList nodes=head.getElementsByTagName("tns:spId");
		NodeList nodepass=head.getElementsByTagName("tns:spPassword");
		if(nodes.item(0).getTextContent().indexOf("wdw")!=-1){
			if(nodepass.item(0).getTextContent().equals("wdwsb")){
				System.out.println("认证成功");
			}
		}
		else{
			SOAPException soapExc=new SOAPException("认证错误");
			throw new Fault(soapExc);
		}
	}
}

  功能:判断客户端传来的soap信息头是否有密码..有的话判断是否正确!

 

3:客户端spring的配置:

 <bean id="webTest" class="org.web.HelloService" factory-bean="client" factory-method="create"/>
	 <bean id="client" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean" >
	 		<property name="address" value="http://127.0.0.1:88/Hello/web/web"></property>
	 		<property name="serviceClass" value="org.web.HelloService"></property>
	 		<property name="outInterceptors">
	 			<list>
					<bean class="org.apache.cxf.interceptor.LoggingOutInterceptor" />  
		            <!--<bean class="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor" />  -->
		            <bean class="org.web.soapHeader.AddSoapHeader"></bean>
		            <!--<bean class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">  
		                <constructor-arg>  
		                    <map>  
		                        <entry key="action" value="UsernameToken" />  
		                        <entry key="passwordType"  value="PasswordText" />  
		                        <entry key="user" value="cxfClient" />  
		                        <entry key="passwordCallbackRef">  
		                            <ref bean="clientPasswordCallback" />  
		                        </entry>  
		                    </map>  
		                </constructor-arg>  
		            </bean>  
	 			-->
	 			</list>
		</property>
	 </bean>

  PS:注意注释>...重点是:

<bean class="org.web.soapHeader.AddSoapHeader"></bean>

 4:对soap进行如入头信息.把密码加进去:AddSoapHeader代码:

public class AddSoapHeader extends AbstractSoapInterceptor {
	private static String nameURI="http://127.0.0.1/Hello/web";
	
	public AddSoapHeader(){
		super(Phase.WRITE);
	}
	public void handleMessage(SoapMessage message) throws Fault {
		SimpleDateFormat sd=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date date=new Date();
		String time =sd.format(date);
		String spPassword="wdwsb";
		String spName="wdw";
		
		QName qname=new QName("RequestSOAPHeader");
		Document doc=DOMUtils.createDocument();
		
		Element spId=doc.createElement("tns:spId");
		spId.setTextContent(spName);
		
		Element spPass=doc.createElement("tns:spPassword");
		spPass.setTextContent(spPassword);
		
		Element root=doc.createElementNS(nameURI, "tns:RequestSOAPHeader");
		root.appendChild(spId);
		root.appendChild(spPass);
		
		SoapHeader head=new SoapHeader(qname,root);
		List<Header> headers=message.getHeaders();
		headers.add(head);
	}
}

  很简单的东西...现在密码已经加进去了...spring里也已经配置好了..

客户端就可以正常的请求了..对请求的内容会进行soap头处理.把密码加进去....

服务端通过了客户端的权限密码请求就可以了.

 

东西很简单..不用过多的讲解了吧...

有什么疑问和见解..请提出来...大家共同学习!!

 

 

........

 

 

 

 

 

 

 

 

 

 

   发表时间:2010-06-02  
所有的SOAP访问都要这样处理吗?那么如何知道该身份的人是否有权限访问这个服务呢?
这里的访问一定没有Session的概念吧?
0 请登录后投票
   发表时间:2010-06-03  
ltian 写道
所有的SOAP访问都要这样处理吗?那么如何知道该身份的人是否有权限访问这个服务呢?
这里的访问一定没有Session的概念吧?




是的..没有session..这个问题暂时还没解决..

你有好的解决方法么?
0 请登录后投票
   发表时间:2010-06-03  
session是有的,客户端每次请求服务端都生成session,返回jsessionid给客户端。
我就是不知道怎么保持客户端和服务端的session?
0 请登录后投票
   发表时间:2010-06-04  
wangchengyong 写道
session是有的,客户端每次请求服务端都生成session,返回jsessionid给客户端。
我就是不知道怎么保持客户端和服务端的session?




呵呵..继续研究...
0 请登录后投票
   发表时间:2010-08-12  
服务端把jsessionid传递给客户端  客户端保存在cookie里
然后  客户端再把jsessionid以隐藏字段的形式传递给服务端
0 请登录后投票
   发表时间:2010-09-28  

cxf 涉及安全方面主要有三个途径。

1. transport level的, https, 通过配置jetty来获得。cxf kit里面有一个例子wsdl_first_https, 很详细的讲了怎么使用https

2. soap message的,也就是通过WS-SECURITY协议对soap消息进行各种签名 加密 时间戳,传输密码(各种不同的Token)等操作,cxf中利用了Apache wss4j这个项目来实现WS-SECURITY, 楼主的例子就是UsernameToken的使用。
cxf kit里面ws_security有不少具体的例子,有兴趣可以看一下。

3.  最简单的方式是使用Http Basic Auth, 这个也是jaxws 规范里面要求必须实现的。

关于cxf security的相关讨论,在cxf maillinglist里面有很多,大家有兴趣可以去查看

Cxf网站上面的User's Guide也对security有详细的讲解。

还有就是FuseSource 也有Cxf的文档, Fuse Services Framework就是基于Apache Cxf.

 

Freeman

------------------------
FuseSource: http://fusesource.com
Apache Servicemix:http://servicemix.apache.org
Apache Cxf: http://cxf.apache.org
Apache Karaf: http://karaf.apache.org
Apache Felix: http://felix.apache.org

0 请登录后投票
   发表时间:2011-03-22  
我的应用场景如下:
接口地址:http://localhost:9763/services/UserWebService?wsdl
其wsdl文本片断如下:
<wsdl:service name="UserWebService"><wsdl:port name="UserWebServiceHttpsSoap11Endpoint" binding="ns:UserWebServiceSoap11Binding"><soap:address location="https://192.168.3.105:9443/services/UserWebService.UserWebServiceHttpsSoap11Endpoint/"/></wsdl:port><wsdl:port name="UserWebServiceHttpSoap11Endpoint" binding="ns:UserWebServiceSoap11Binding"><soap:address location="http://192.168.3.105:9763/services/UserWebService.UserWebServiceHttpSoap11Endpoint/"/></wsdl:port><wsdl:port name="UserWebServiceHttpsSoap12Endpoint" binding="ns:UserWebServiceSoap12Binding"><soap12:address location="https://192.168.3.105:9443/services/UserWebService.UserWebServiceHttpsSoap12Endpoint/"/></wsdl:port><wsdl:port name="UserWebServiceHttpSoap12Endpoint" binding="ns:UserWebServiceSoap12Binding"><soap12:address location="http://192.168.3.105:9763/services/UserWebService.UserWebServiceHttpSoap12Endpoint/"/></wsdl:port><wsdl:port name="UserWebServiceHttpEndpoint" binding="ns:UserWebServiceHttpBinding"><http:address location="http://192.168.3.105:9763/services/UserWebService.UserWebServiceHttpEndpoint/"/></wsdl:port><wsdl:port name="UserWebServiceHttpsEndpoint" binding="ns:UserWebServiceHttpBinding"><http:address location="https://192.168.3.105:9443/services/UserWebService.UserWebServiceHttpsEndpoint/"/></wsdl:port></wsdl:service>

现在我要访问https对应的端点,迁扯到证书方面的问题,请问下,我应怎么去做呢,
0 请登录后投票
   发表时间:2011-05-24  
如果你的data有安全性要求,只用WS-SECURITY是无法满足的,SSL是比较简单安全的方法。我个人不建议走WS_*路线。
Web services的设计思想是无状态的,所以是没有session这个概念的,当然你可以自己实现security token 来代替 hashed password
Http Basic Auth+SSL从安全性看问题不大,但是不是一个好的设计模式对externel webservice,在WS-SECURITY中timestamp是用来做避免重访攻击的。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics