2012-08-17 70 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的處理程序框架的優秀文章。

希望這會有所幫助。