开发了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>

  

posted on 2013-12-11 15:42  TinyPI  阅读(1431)  评论(0编辑  收藏  举报