2014-10-28 59 views
5

我有一個與SOAP服務交互的java應用程序。我使用WSDL通過CXF生成一個java客戶端,但我需要使用ws-security來驗證我的呼叫。我正在尋找一種代碼方式來做到這一點,我沒有任何XML配置。這是我已經嘗試過:帶有Apache CXF的WS-Security UsernameToken

Map ctx = ((BindingProvider)port).getRequestContext(); 
ctx.put("ws-security.username", "joe"); 
ctx.put("ws-security.password", "joespassword"); 
port.makeSoapCall(); 

但是我得到一個無效的WS-Security頭解析錯誤。什麼是正確的方法來做到這一點?

在SOAP UI,我可以通過右鍵單擊SOAP頭,點擊「添加WSS的UsernameToken」,然後選擇「密碼文本」

回答

4

您按照您共享的代碼使用WS-SecurityPolicy。如何僅使用WS-Security並使用WSS4JOutInterceptor通過usernametoken進行發送?

檢查節中的Apache CFX的WS-Security蒞臨指導「通過API添加攔截器」:http://cxf.apache.org/docs/ws-security.html

這是需要做的事情就像上面的Apache CXF documenation上面什麼​​。你可能只需要外面的攔截器路徑。

在客戶端,您可以獲取使用ClientProxy助手到CXF端點引用:

import org.apache.cxf.frontend.ClientProxy; 
... 

GreeterService gs = new GreeterService(); 
Greeter greeter = gs.getGreeterPort(); 
... 
org.apache.cxf.endpoint.Client client = ClientProxy.getClient(greeter); 
org.apache.cxf.endpoint.Endpoint cxfEndpoint = client.getEndpoint(); 

現在您可以添加攔截器:

import org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor; 
import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor; 
... 

Map<String,Object> inProps = new HashMap<String,Object>(); 
... // how to configure the properties is outlined below; 

WSS4JInInterceptor wssIn = new WSS4JInInterceptor(inProps); 
cxfEndpoint.getInInterceptors().add(wssIn); 

Map<String,Object> outProps = new HashMap<String,Object>(); 
outProps.put("action", "UsernameToken Timestamp"); 
outProps.put("passwordType", "PasswordDigest"); //remove this line if want to use plain text password 
outProps.put("user", "abcd"); 
outProps.put("passwordCallbackClass", "demo.wssec.client.UTPasswordCallback"); 

WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps); 
cxfEndpoint.getOutInterceptors().add(wssOut); 

您將需要在上面的示例中編寫密碼回調類(UTPasswordCallback)。

的Apache CXF和用戶名的完整示例令牌這裏:http://svn.apache.org/repos/asf/cxf/trunk/distribution/src/main/release/samples/ws_security/ut/

從上面的鏈接瀏覽到用戶名令牌和UTPasswordCallback代碼客戶端文件夾中(src /主/ JAVA /演示/ wssec /客戶端)。

編輯:如果您的wsdl需要密碼爲純文本,那麼只需從代碼中刪除此行: outProps.put(「passwordType」,「PasswordDigest」);