开发了JEE一个项目,项目中开发了一些webservice接口,是用cxf框架实现的,其中添加了一个基本的安全验证(用的用户密码的验证,UsernameToken)。
可能是一开始沟通的不到位,导致另一个项目组的人员调用我们的webservice接口时,添加安全验证出现的麻烦。(对方是用的jax-ws,jdk中最基本的webservice客端来调用的),怎么做来让jax-ws来通过cxf的安全验证呢?
首先要搭建好一个没有安全验证的cxf框架的webservice服务。
第二是生产客户端代码,成功调用cxf发布的服务。
调式使客户的成功调用webservice服务。
下面是添加安全验证:
服务端添加安全验证
<jaxws:endpoint id="helloService" address="helloService" implementor="com.ws.impl.HelloService" > <jaxws:inInterceptors> <bean class="org.apache.cxf.interceptor.LoggingInInterceptor" /> <bean class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor" /> <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" value-ref="myPasswordCallback" /> </map> </constructor-arg> </bean> </jaxws:inInterceptors> </jaxws:endpoint>
配置好服务端的安全验证。
客户端添加安全验证。如果客户端用cxf框架的话,安全验证跟好加上
这是用cxf请求的数据的header
<SOAP-ENV:Header xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" soap:mustUnderstand="1"> <wsse:UsernameToken wsu:Id="UsernameToken-1"> <wsse:Username> admin </wsse:Username> <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText"> password </wsse:Password> </wsse:UsernameToken> </wsse:Security> </SOAP-ENV:Header>
。
下面来用jax-ws来添加安全验证:
客户端类型下面的代码
HelloServiceService helloService; helloService = new HelloServiceService(); helloService.setHandlerResolver(new HandlerResolver() { public List<Handler> getHandlerChain(PortInfo arg0) { List<Handler> handlerList = new ArrayList<Handler>(); handlerList.add(new ClientAuthenticationHandler()); return handlerList; } }); HelloService helloClient = helloService.getHelloServicePort(); helloClinet.sayHello("admin");
然后实现
ClientAuthenticationHandler
import java.util.Set; import javax.xml.namespace.QName; import javax.xml.soap.SOAPElement; import javax.xml.soap.SOAPEnvelope; import javax.xml.soap.SOAPHeader; import javax.xml.soap.SOAPHeaderElement; import javax.xml.soap.SOAPMessage; import javax.xml.ws.handler.MessageContext; import javax.xml.ws.handler.soap.SOAPHandler; import javax.xml.ws.handler.soap.SOAPMessageContext; public class ClientAuthenticationHandler implements SOAPHandler<SOAPMessageContext> { public Set<QName> getHeaders() { // TODO Auto-generated method stub return null; } public void close(MessageContext arg0) { // TODO Auto-generated method stub } public boolean handleFault(SOAPMessageContext arg0) { // TODO Auto-generated method stub return false; } public boolean handleMessage(SOAPMessageContext ctx) { Boolean request_p = (Boolean) ctx .get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); if (request_p) { try { SOAPMessage msg = ctx.getMessage(); SOAPEnvelope env = msg.getSOAPPart().getEnvelope(); SOAPHeader hdr = env.getHeader(); if (hdr == null) hdr = env.addHeader(); SOAPHeaderElement security = (SOAPHeaderElement) hdr.addChildElement("Security", "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"); security.setAttribute("xmlns:wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"); security.setMustUnderstand(true); SOAPElement userNameToken = security.addChildElement("UsernameToken", "wsse"); userNameToken.setAttribute("wsu:Id", "UsernameToken-1"); userNameToken.addChildElement("Username", "wsse").addTextNode("admin"); SOAPElement password = userNameToken.addChildElement("Password", "wsse"); password.setAttribute("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText"); password.addTextNode("password"); msg.saveChanges(); return true; } catch (Exception e) { e.printStackTrace(); } } return false; } }
在这个handler里面来实现对数据请求报中header的操作。
下面是拦截的数据包的 header:
<S:Header> <wsse:Security xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" SOAP-ENV:mustUnderstand="1"> <wsse:UsernameToken wsu:Id="UsernameToken-1"> <wsse:Username> admin </wsse:Username> <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText"> password </wsse:Password> </wsse:UsernameToken> </wsse:Security> </S:Header>