I would like to use the CXF web service from a .net C # client. Currently, we work with java-to-java requests and protect SOAP envelopes through ws-security (WSS4J library).
My question is: how can I implement a C # WS client that generates the same SOAP requests as the following client-side Java code?
//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;
Does anyone know where I can find a Microsoft practical example or a working .net example?
============================ EDIT ====================== =================================================== ===============
Thank Ladislav I applied your suggestions and I came up with something like:
X509Certificate2 client_pk, server_cert;
client_pk = new X509Certificate2(@"C:\x509\clientKey.pem", "blablabla");
server_cert = new X509Certificate2(@"C:\x509\server-cert.pfx", "blablabla");
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;
myBinding.Security.Message.NegotiateServiceCredential = false;
myBinding.Security.Message.EstablishSecurityContext = false;
EndpointAddress ea =
new EndpointAddress(new Uri("http://bla.bla.bla"),
EndpointIdentity.CreateDnsIdentity("issuer"));
UsernameClientCredentials credentials = new UsernameClientCredentials(new
UsernameInfo("superadmin", "secret"));
PersistenceClient client = new PersistenceClient(myBinding, ea);
client.Endpoint.Contract.ProtectionLevel =
System.Net.Security.ProtectionLevel.EncryptAndSign;
client.Endpoint.Behaviors.Remove(typeof(ClientCredentials));
client.Endpoint.Behaviors.Add(credentials);
client.ClientCredentials.ClientCertificate.Certificate = client_pk;
client.ClientCredentials.ServiceCertificate.DefaultCertificate = server_cert;
client.Open();
clientProxyNetwork[] response = client.GetAllNetwork();
As a result, I get (server side) the following CXF exception:
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)
Therefore, this seems like a problem with jks-> pem conversion ... Or am I missing something in the client code above?