2012-12-05 23 views
0

我希望能夠動態更改/設置每個發送cxf中的soap消息的ws-security信息。這怎麼能做到最好。如何在CXF中發送soap消息時使用ws-security信息?

詳細信息:我想更改像密鑰庫名稱,密鑰存儲別名,密碼,主機名等設置。在運行時期間,最好每個發送消息。 目前我正在使用:帶有WSS4JOutInterceptor和WSS4JInInterceptor攔截器的jaxws客戶端進行簽名。我正在使用http管道和tls客戶端參數進行SSL/TLS通信。 jaxws客戶端和http管道都是在spring中配置的,並且具有像在Spring配置中設置的密鑰庫名稱,別名和密碼一樣的配置。

我看到選項: 1)我在運行時通過全局屬性更改這些設置。 2)我更改這些設置每發送消息(最好)。

2)雖然可取,但我覺得最困難。 我該怎麼做? a)jaxws客戶端:根據消息所需的安全設置,製作我自己的進出攔截器,攔截消息並使用正確的(緩存的)WSS4JOutInterceptor攔截器。如果WSS4JOutInterceptor攔截器不存在於緩存中,則會創建它(我可能已緩存最多5個WSS4JOutInterceptor實例)。 但是,如何確定在我的攔截器中需要哪些設置,因爲在與@Webservice代理通信時創建和發送肥皂請求/消息時,該應用的其他部分已知此設置... 也許我可以通過JaxWsClientProxy添加某種securityInfo對象到肥皂消息,但是如何?... 也許我可以在發送/創建肥皂消息時設置攔截器,當這個安全信息仍然知道。這將是一個包含所需設置的輕量攔截器,鏈接到緩存的攔截器,這取決於設置選擇...

b)http導管:使用ConduitSelector(從未使用過但會發現) ,這樣我可以選擇正確的http管道,但是我有和(a)中相同的問題:「如何確定我應該使用哪些設置」,因爲它們在創建/發送肥皂消息時已知,攔截器是設置後... 可能是我設置每發送消息的管道選擇..

在結束上述成爲一個大的故事),但我希望這是清楚你能給些建議嗎?

+0

這是橫貼在Apache CXF郵件列表上,並獲得更多的討論有:。HTTP ://www.mail-archive.com/[email protected]/msg29770.html – EpicVoyage

回答

0

我發現org.apache.cxf軟件包對於我不必編寫自定義類並且能夠堅持基本界面非常有幫助。

爲實例,這種方法可能是:

  • 使用JAX-WSwsimport客戶
  • 使用cxfWSS4JOutInterceptor帶有動態屬性
  • 使用動態CallbackHandler類用於訪問密鑰庫

典型的(wsimport'd)客戶端公共API可能會確定這樣的:

public class SomeServiceClient 
{ 

    public SomeService getSomeService(URL url) 
    { 

    SomeService_Service svc = new SomeService_Service(); 

    SomeService someService = svc.getSomeServicePort(); 

    Client client = ClientProxy.getClient(someService); 
    Endpoint cxfEP = client.getEndpoint(); 

    Map<String, Object> outProps = new HashMap<String, Object>(); 
    outProps.put(WSHandlerConstants.ACTION, "Signature"); 
    outProps.put(WSHandlerConstants.USER, "foo"); 
    outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, SomeClientCallbackHandler.class.getName()); 
    outProps.put(WSHandlerConstants.SIG_PROP_FILE, "client-sign.properties"); 

    WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps); 

    cxfEP.getOutInterceptors().add(wssOut); 

    return someService; 
    } 
} 

你能提供一些邏輯,以確定哪些WSHandlerConstants.USER值傳遞,使用哪個PW_CALLBACK_CLASS,並且要使用的SIG_PROP_FILE

屬性文件可能如下所示。你可以簡單地有多個文件可以選擇,或者在課堂上,你可能只是動態添加這些屬性:

# properties for accessing the java keystore using Merlin 
org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin 
org.apache.ws.security.crypto.merlin.keystore.type=jks 
org.apache.ws.security.crypto.merlin.keystore.password=bar 
org.apache.ws.security.crypto.merlin.keystore.alias=foo 
org.apache.ws.security.crypto.merlin.keystore.file=foobar.keystore 

最後,您CallbackHandler需要提供你的密鑰庫中確定的證書的別名密碼。這也可能有一些動態的邏輯。

public class SomeClientCallbackHandler implements CallbackHandler 
{ 

    @Override 
    public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException 
    { 
     for(Callback thisCallback : callbacks) 
     { 
      WSPasswordCallback pwcb = (WSPasswordCallback)thisCallback; 
      String user = pwcb.getIdentifier(); 
      int usage = pwcb.getUsage(); 

      if(usage == WSPasswordCallback.SIGNATURE) 
      { 
       if("foo".equals(user)) pwcb.setPassword("bar"); 
      } 
     }   
    } 
} 

最後,沒有太多的工作要做到這一切「動態」來處理多個密鑰庫,而不是隻做一次工作。編碼你自己的'in'或'out'攔截器可能會更好。

0

的接受這個問題的答案似乎是(從http://www.mail-archive.com/[email protected]/msg29804.html):

埃德嗨,

正如我已經寫了,你甚至不需要攔截改變 屬性。您可以通過發送消息在您的客戶端執行此操作:

AddNumbers port =(AddNumbers)service.getPort(portName, AddNumbers.class); ((BindingProvider)port).getRequestContext()。put(SecurityConstants.ENCRYPT_PROPERTIES, )。

雖然如果您想在攔截器中執行此操作,您可以使用相同的技術通過 必要的信息和消息屬性。

控制CXF中安全性的最標準和推薦的方法是使用WS-Policy的 。您也可以在運行時動態應用它。如果 這種方式對您很有趣,我可以提供更多信息 如何動態設置WS-Policy。

乾杯,安德烈。

(從http://www.mail-archive.com/[email protected]/msg29809.html):

如果你: ((BindingProvider)端口).getRequestContext()把(「thread.local.request。語境」, ‘真’);

比getRequestContext(未來的呼叫)將使用一個線程局部 請求上下文這使得請求上下文是線程安全的 (注:響應上下文總是線程本地。 CXF)

詳細信息 http://cxf.apache.org/faq.html#FAQ-AreJAXWSclientproxiesthreadsafe%3F

乾杯,安德烈