Java调用ws-security的web服务

lixun033

贡献于2013-10-25

字数:5485 关键词: WEB服务/RPC/SOA Java

Java调用ws-security的web服务 本文档用于指导使用java程序编写客户端调用带有安全认证的web服务,安全认证是指ws-security标准。ws-security提供了一些强大的特性来保障 Web 服务应用程序的安全,这里特指使用用户名密码方式的鉴权方式。我们将使用cxf和wss4j两个框架实现客户端调用带有安全认证的web服务。同时我们还可以利用cxf为soap请求的header中加入自定义的属性。 1. 场景说明 场景中定义了一个webservice服务,其url地址为:http://172.16.13.203:4888/services/wsWithSecurityTest?wsdl。 其中有方法:testOperation,有一个字符串入参:input,有一个字符串返回参数:output; 函数的功能:在入参input前加入字符串“you input is :”返回给调用者。比如:调用testOperation,传入参数“hello”,方法返回“you input is :hello”。 同时该方法通过ws-security使用用户名密码方式的鉴权,用户名为“user”,密码为“pass” 。 2.客户端编写过程 1. 下载cxf 在apache官网下载cxf,下载地址为: http://www.apache.org/dyn/closer.cgi?path=/cxf/2.2.12/apache-cxf-2.2.12.zip 2. 利用cxf生成访问代理类 将下载的apache-cxf-2.2.12.zip解压,在解压后的文件目录中找到bin文件夹的wsdl2java文件,通过控制台窗口利用该命令文件生成调用web服务的代理类。命令格式如下: wsdl2java –client http://172.16.13.203:4888/services/wsWithSecurityTest?wsdl 在当前目录会生成一个com文件夹,里面包含了自动生成的代理类。生成的类的列表如下图所示: 3. 编写访问代码 1) 在eclipse中新建一个java工程,取名为wsClient。将上步中生成的com文件夹拷贝至新建工程中的src目录中。并将下图所示所有的包引进工程。 2) 新建类包com.apusic.esb.call,在这个包里面新建三个类“WSCallBackHandler”、“WSCallSoapInterceptor”以及“MyClient”。 WSCallBackHandler是用于获取密码的回调处理类,他继承于CallbackHandler。具体的编码实现如下所示: package com.apusic.esb.call; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import org.apache.ws.security.WSPasswordCallback; public class WSCallBackHandler implements CallbackHandler { @Override public void handle(Callback[] callbacks) { for (Callback callback : callbacks) { if(callback instanceof WSPasswordCallback){ WSPasswordCallback wspc = (WSPasswordCallback)callback; if(wspc.getIdentifier().equals("user")){ wspc.setPassword("pass"); } } } } } WSCallSoapInterceptor是用于在soapHeader中添加自定义属性的拦截器类,他继承于AbstractSoapInterceptor。具体的编码实现如下所示: package com.apusic.esb.call; import java.util.List; import javax.xml.namespace.QName; import org.apache.cxf.binding.soap.SoapHeader; import org.apache.cxf.binding.soap.SoapMessage; import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor; import org.apache.cxf.headers.Header; import org.apache.cxf.helpers.DOMUtils; import org.apache.cxf.interceptor.Fault; import org.apache.cxf.phase.Phase; import org.w3c.dom.Document; import org.w3c.dom.Element; public class WSCallSoapInterceptor extends AbstractSoapInterceptor { public WSCallSoapInterceptor() { super(Phase.WRITE); } @Override public void handleMessage(SoapMessage message) throws Fault { List
headers=message.getHeaders(); QName qName=new QName("RequestSOAPHeader"); Document document=DOMUtils.createDocument(); Element element=document.createElement("spId"); element.setTextContent("myappid"); SoapHeader header=new SoapHeader(qName, element); headers.add(header); } } MyClient只有一个main函数,用于编码实现调用web服务,在此处将用户名传入。代码如下所示: package com.apusic.esb.call; import java.util.HashMap; import java.util.Map; import org.apache.cxf.endpoint.Client; import org.apache.cxf.endpoint.Endpoint; import org.apache.cxf.frontend.ClientProxy; import org.apache.cxf.interceptor.LoggingOutInterceptor; import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor; import org.apache.ws.security.WSConstants; import org.apache.ws.security.handler.WSHandlerConstants; import com.apusic.esb.wswithsecuritytest.WsWithSecurityTest; import com.apusic.esb.wswithsecuritytest.WsWithSecurityTestInterface; public class MyClient { public static void main(String[] args) { WsWithSecurityTest server = new WsWithSecurityTest(); WsWithSecurityTestInterface port = server.getPort(WsWithSecurityTestInterface.class); Client c = ClientProxy.getClient(port); //下面代码通过拦截器加入自定义soapHeard c.getOutInterceptors().add(new WSCallSoapInterceptor()); //下面代码通过回调对用户名密码的WSsecurity验证 Endpoint endPoint = c.getEndpoint(); Map outProps = new HashMap(); outProps.put(WSHandlerConstants.ACTION, WSConstants.USERNAME_TOKEN_LN); outProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_DIGEST); outProps.put(WSHandlerConstants.USER, "uu"); outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, WSCallBackHandler.class.getName()); //在后台打印soup消息 endPoint.getOutInterceptors().add(new LoggingOutInterceptor()); //加入权限控制 endPoint.getOutInterceptors().add(new WSS4JOutInterceptor(outProps)); // //////////////////////////////////////////// System.out.println(port.testOperation("hi")); } } 注意上面的这行代码: endPoint.getOutInterceptors().add(new LoggingOutInterceptor()); 通过它会在控制台中打出soap请求的原文,soap请求如下所示: ID: 1 Address: http://172.16.13.158:4888/services/wsWithSecurityTest Encoding: UTF-8 Content-Type: text/xml Headers: {SOAPAction=["http://www.apusic.com/esb/wsWithSecurityTest/testOperation"], Accept=[*/*]} Payload: uu65MFj16KhvbHQz1x/tyIoN7vcE8=VVWdf9M3RwzW9Pv1CnWSbw==2011-11-22T06:22:53.705Zmyappidhi -------------------------------------- 上面标红的是ws-security的验证消息,标蓝的是自定义的soapHeader的属性.

下载文档,方便阅读与编辑

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 5 金币 [ 分享文档获得金币 ]
0 人已下载

下载文档

相关文档