锁定老帖子 主题:CXF 密码权限控制 SOAP报头处理
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-06-01
前一段时间写了一篇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头处理.把密码加进去.... 服务端通过了客户端的权限密码请求就可以了.
东西很简单..不用过多的讲解了吧... 有什么疑问和见解..请提出来...大家共同学习!!
........
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-06-02
所有的SOAP访问都要这样处理吗?那么如何知道该身份的人是否有权限访问这个服务呢?
这里的访问一定没有Session的概念吧? |
|
返回顶楼 | |
发表时间:2010-06-03
ltian 写道 所有的SOAP访问都要这样处理吗?那么如何知道该身份的人是否有权限访问这个服务呢?
这里的访问一定没有Session的概念吧? 是的..没有session..这个问题暂时还没解决.. 你有好的解决方法么? |
|
返回顶楼 | |
发表时间:2010-06-03
session是有的,客户端每次请求服务端都生成session,返回jsessionid给客户端。
我就是不知道怎么保持客户端和服务端的session? |
|
返回顶楼 | |
发表时间:2010-06-04
wangchengyong 写道 session是有的,客户端每次请求服务端都生成session,返回jsessionid给客户端。 我就是不知道怎么保持客户端和服务端的session? 呵呵..继续研究... |
|
返回顶楼 | |
发表时间:2010-08-12
服务端把jsessionid传递给客户端 客户端保存在cookie里
然后 客户端再把jsessionid以隐藏字段的形式传递给服务端 |
|
返回顶楼 | |
发表时间:2010-09-28
cxf 涉及安全方面主要有三个途径。 Cxf网站上面的User's Guide也对security有详细的讲解。 还有就是FuseSource 也有Cxf的文档, Fuse Services Framework就是基于Apache Cxf.
Freeman |
|
返回顶楼 | |
发表时间: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对应的端点,迁扯到证书方面的问题,请问下,我应怎么去做呢, |
|
返回顶楼 | |
发表时间:2011-05-24
如果你的data有安全性要求,只用WS-SECURITY是无法满足的,SSL是比较简单安全的方法。我个人不建议走WS_*路线。
Web services的设计思想是无状态的,所以是没有session这个概念的,当然你可以自己实现security token 来代替 hashed password Http Basic Auth+SSL从安全性看问题不大,但是不是一个好的设计模式对externel webservice,在WS-SECURITY中timestamp是用来做避免重访攻击的。 |
|
返回顶楼 | |
浏览 12057 次