.net WCF - совместимость CXF / WSS4j - PullRequest
3 голосов
/ 22 января 2011

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

Мой вопрос: как мне реализовать клиент C # 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 ... Или я что-то упустил в коде клиента выше?

Ответы [ 2 ]

1 голос
/ 31 декабря 2011

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

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

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

0 голосов
/ 22 января 2011

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

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

...