2011-01-22 82 views
3

我想從.net c#客戶端使用CXF Web服務。我們目前正在使用java-to-java請求,我們通過ws-security(WSS4J庫)保護SOAP信封。.net WCF - CXF/WSS4j互操作性

我的問題是:我如何實現一個C#WS客戶端,它產生與以下客戶端Java代碼相同的SOAP請求?

//doc is the original SOAP envelope to process with WSS4J 
WSSecHeader secHeader = new WSSecHeader(); 
secHeader.insertSecurityHeader(doc); 

//add username token with password digest 
WSSecUsernameToken usrNameTok = new WSSecUsernameToken(); 
usrNameTok.setPasswordType(WSConstants.PASSWORD_DIGEST); 
usrNameTok.setUserInfo("guest",psw_guest); 
usrNameTok.prepare(doc); 
usrNameTok.appendToHeader(secHeader); 

//sign the envelope body with client key 
WSSecSignature sign = new WSSecSignature(); 
sign.setUserInfo("clientx509v1", psw_clientx509v1); 
sign.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE); 

Document signedDoc = null;  
sign.prepare(doc, sigCrypto, secHeader); 
signedDoc = sign.build(doc, sigCrypto, secHeader); 

//encrypt envelope body with server public key 
WSSecEncrypt encrypt = new WSSecEncrypt(); 
encrypt.setUserInfo("serverx509v1"); 

// build the encrypted SOAP part 
String out = null; 
Document encryptedDoc = encrypt.build(signedDoc, encCrypto, secHeader); 
return encryptedDoc; 

有誰知道我在哪裏能找到一個微軟如何對或.NET的例子嗎?

================================編輯============= =======================

謝謝Ladislav!我申請了你的建議,我想出了喜歡的東西:

X509Certificate2 client_pk, server_cert; 
client_pk = new X509Certificate2(@"C:\x509\clientKey.pem", "blablabla"); 
server_cert = new X509Certificate2(@"C:\x509\server-cert.pfx", "blablabla"); 

// Create the binding. 
System.ServiceModel.WSHttpBinding myBinding = new WSHttpBinding();  
myBinding.TextEncoding = ASCIIEncoding.UTF8; 
myBinding.MessageEncoding = WSMessageEncoding.Text;    
myBinding.Security.Mode = SecurityMode.Message; 
myBinding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate; 
myBinding.Security.Message.AlgorithmSuite =           
      System.ServiceModel.Security.SecurityAlgorithmSuite.Basic128; 

// Disable credential negotiation and the establishment of 
// a security context. 
myBinding.Security.Message.NegotiateServiceCredential = false; 
myBinding.Security.Message.EstablishSecurityContext = false;     

// Create the endpoint address. 
EndpointAddress ea = 
    new EndpointAddress(new Uri("http://bla.bla.bla"), 
      EndpointIdentity.CreateDnsIdentity("issuer")); 

// configure the username credentials on the channel factory 
UsernameClientCredentials credentials = new UsernameClientCredentials(new 
            UsernameInfo("superadmin", "secret")); 

// Create the client. 
PersistenceClient client = new PersistenceClient(myBinding, ea); 

client.Endpoint.Contract.ProtectionLevel = 
      System.Net.Security.ProtectionLevel.EncryptAndSign; 

// replace ClientCredentials with UsernameClientCredentials 
client.Endpoint.Behaviors.Remove(typeof(ClientCredentials)); 
client.Endpoint.Behaviors.Add(credentials); 

// Specify a certificate to use for authenticating the client. 
client.ClientCredentials.ClientCertificate.Certificate = client_pk; 

// Specify a default certificate for the service. 
client.ClientCredentials.ServiceCertificate.DefaultCertificate = server_cert; 

// Begin using the client. 
client.Open(); 
clientProxyNetwork[] response = client.GetAllNetwork(); 

結果我得到(服務器端)以下CXF例外:

java.security.SignatureException: Signature does not match. 
at sun.security.x509.X509CertImpl.verify(X509CertImpl.java:421) 
at sun.security.provider.certpath.BasicChecker.verifySignature(BasicChecker.java:133) 
at sun.security.provider.certpath.BasicChecker.check(BasicChecker.java:112) 
at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate (PKIXMasterCertPathValidator.java:117) 

因此它似乎是一個關鍵jks-> PEM轉換問題......或者我在上面的客戶端代碼中丟失了一些東西?

+0

我知道這是一個非常古老的問題,但我現在正在嘗試做類似的事情,但不幸的是我不能。我試過你的代碼,但我不能引用`UsernameClientCredentials`這是你的自定義類嗎?基本上我必須用UsernameToken,BinarySecurityToken和Signature創建安全標頭 – Misiu 2017-02-13 13:36:12

回答

1

那麼,最終解決方案是加密和簽署整個用戶名令牌。至於互操作性,必須在cxf中激活ws尋址,並且需要在c#中進行自定義綁定。訣竅的自定義綁定基本上是

AsymmetricSecurityBindingElement abe = 
    (AsymmetricSecurityBindingElement)SecurityBindingElement. 
CreateMutualCertificateBindingElement(MessageSecurityVersion. 
WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10); 
                

Wcf標記每個ws尋址元素,因此必須完成相同的服務器端。

0

這通常是相當大的問題,因爲WCF does not support UserNameToken Profile with Digested password。我在幾個月前編寫了needed it,我們必須實現我們自己的自定義綁定,但該代碼尚未準備好發佈。 Fortunatelly this blog article描述了其他實施方式,並且包含支持消化密碼的具有新的UserNameClientCredentials類的示例代碼。

Btw。對於名爲WSE 3.0的較舊的API,應該可以使用相同的安全配置。它被WCF所取代,但仍然有一些WS- *堆棧配置比這個API和舊的ASMX服務更簡單。