2012-08-17 120 views

回答

2

根据Amila Suriarachchi的文章"Securing Web Service Integration"“WSO2 carbon支持UT,即使通过转换POX消息来进行HTTP基本认证”,但我不确定这是否与您的兴趣相关。

但是,使用JAX-WS客户端配置UsernameToken授权并不像看起来那么困难。您所要做的就是创建一个实现javax.xml.ws.handler.soap.SOAPHandler的类,并通过覆盖handleMessage(SOAPMessageContext messageContext)方法在出站消息中添加安全头。

我的Java版本是1.6.0_26(没有应用上述补丁),Web服务客户端存根类由JAX-WS RI 2.1.7根据Web服务的wsdl生成,由UsernameToken场景,并由WSO2 Carbon服务器(即Data Services Server-2.6.3)公开

我使用Apache WSS4J创建安全头 - 在这种情况下,只需实例化org.apache.ws.security.message.WSSecUsernameToken对象并通过setUserInfo(String user,String password)方法设置用户名和密码。此外,还应将时间戳记元素添加到传出SOAP消息的安全性标头中。 示例实现看起来是这样的:

public boolean handleMessage(SOAPMessageContext messageContext) { 
    Boolean isOutboundMessage = (Boolean) messageContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); 

    if (isOutboundMessage) { 
     SOAPPart messageSoapPart = messageContext.getMessage().getSOAPPart(); 

     WSSecHeader securityHeader = new WSSecHeader(); 
     securityHeader.insertSecurityHeader(messageSoapPart); 
     WSSecUsernameToken usernameToken = new WSSecUsernameToken(); 

     usernameToken.setPasswordType(WSConstants.PASSWORD_TEXT); 
     usernameToken.setUserInfo("root", "top_secret"); 

     WSSecTimestamp timestamp = new WSSecTimestamp(); 

     usernameToken.build(messageSoapPart, securityHeader); 
     timestamp.build(messageSoapPart, securityHeader); 
    } 

    return true; 
} 

提到另一个重要的事情是,SOAP头元素可能附带的mustUnderstand全球SOAP属性。参考Jim White撰写的文章Working with Headers in JAX-WS SOAPHandlers,该属性用于指示Web服务接收器或中介是否需要在处理消息之前理解标题元素。

如果mustUnderstand元素设置为true(soapenv:mustUnderstand =“1”),则应对getHeaders()方法进行编码,以告知运行时环境SOAP处理程序将负责处理mustUnderstand头元素返回一组匹配mustUnderstand头元素的QName(限定名称)对象。以下是处理安全性标头的getHeaders()方法。

public Set<QName> getHeaders() { 
    final String NAMESPACE_URI = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"; 
    final String LOCAL_PART = "Security"; 
    final String PREFIX = "wsse"; 

    final QName wssecurity = new QName(NAMESPACE_URI, LOCAL_PART, PREFIX); 
    final Set<QName> headers = new HashSet<QName>(); 
    headers.add(wssecurity); 

    return headers; 
} 

最后,得到了服务端口,并调用它的任何方法要注册上述类的一个实例之前(比方说 - UsernameTokenSecuritySoapHandler)到您的Web服务客户端的处理程序链。这可以通过使用下面的代码来完成:

Service service = new Service(); 
    service.setHandlerResolver(new HandlerResolver() { 
     public List<Handler> getHandlerChain(PortInfo portInfo) { 
      List<Handler> handlers = new ArrayList<Handler>(); 
      handlers.add(new UsernameTokenSecuritySoapHandler()); 
      return handlers; 
     } 
    }); 

另外 - 你会发现here由小杨对JAX-WS API的处理程序框架的优秀文章。

希望这会有所帮助。