Совместимость .net WCF и CXF/WSS4j

Я хотел бы использовать веб-службу CXF из клиента .net С#. В настоящее время мы работаем с запросами java-to-java и защищаем конверты SOAP через ws-security (библиотека WSS4J).

Мой вопрос: как я могу реализовать WS-клиент С#, который создает те же запросы SOAP, что и следующий код Java на стороне клиента?

//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;

Кто-нибудь знает, где я могу найти руководство Microsoft или рабочий пример .net?

================================ РЕДАКТИРОВАТЬ ================= ====================

Спасибо, Ладислав! Я применил ваши предложения, и я придумал что-то вроде:

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... Или я что-то упустил в клиентском коде выше?


person matteo rulli    schedule 22.01.2011    source источник
comment
Я знаю, что это очень старый вопрос, но я пытаюсь сделать то же самое прямо сейчас, но, к сожалению, не могу. Я попробовал ваш код, но не могу сослаться на него UsernameClientCredentials это ваш пользовательский класс? В основном я должен создать заголовок безопасности с UsernameToken, BinarySecurityToken и Signature   -  person Misiu    schedule 13.02.2017
comment
@Misiu Вы нашли какое-нибудь решение для этой ситуации?   -  person Tagi    schedule 29.03.2021
comment
@Tagi извините за поздний ответ. Я создал собственный класс, который реализует IClientMessageInspector, и в основном он создает XML-запрос вручную. К сожалению, у меня больше нет доступа к исходному коду.   -  person Misiu    schedule 30.03.2021
comment
@Misiu Вы создали полный запрос или только заголовок безопасности? Спасибо за ваш ответ.   -  person Tagi    schedule 31.03.2021
comment
@Tagi, если я правильно помню, я добавил только весь заголовок безопасности.   -  person Misiu    schedule 01.04.2021


Ответы (2)


Ну, в конце концов, решение состоит в том, чтобы зашифровать и подписать весь токен имени пользователя. Что касается совместимости, адресация ws должна быть активирована в cxf и необходима пользовательская привязка в c#. Пользовательская привязка, которая сделала свое дело, в основном

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

Wcf подписывает каждый элемент адресации ws, поэтому то же самое необходимо делать на стороне сервера.

person matteo rulli    schedule 30.12.2011

Обычно это довольно большая проблема, поскольку WCF не поддерживает профиль UserNameToken с переработанным паролем. Мне это нужно несколько месяцев назад, и нам пришлось реализовать собственную пользовательскую привязку, но этот код не готов к публикации. К счастью, эта статья в блоге описывает другую реализацию и содержит пример кода с новым классом UserNameClientCredentials, поддерживающим переработанный пароль.

Кстати. такая же конфигурация безопасности должна быть возможна с более старым API, называемым WSE 3.0. Он был заменен WCF, но все же некоторые конфигурации стека WS-* намного проще с этим API и старыми службами ASMX.

person Ladislav Mrnka    schedule 22.01.2011