Я работаю в большом проекте, который широко использует WCF для различных видов связи. В рамках нового требования нам необходимо связаться с веб-службой SOAP, разработанной третьей стороной. Их служба разработана с Java и имеет два требования безопасности:WCF Связывание с транспортом и безопасностью сообщений
он нуждается BASIC аутентификации по транспорту и
сообщение должно быть подписано (не шифруются) с X509 сертификата с использованием WS-Security (OASIS) стандарт для неотказуемости.
У меня есть проблема в том, что переплеты, предоставляемые WCF позволяют использовать либо транспорт или безопасность сообщений, но не оба одновременно. В результате я могу либо подписать SOAP-сообщение, либо отправить учетные данные BASIC, но до сих пор мне не удалось выполнить оба эти требования.
Я пытаюсь найти решение в течение нескольких дней, и до сих пор я пришел к выводу, что, вероятно, мой лучший снимок - сделать программную привязку программно. Использование нескольких источников, это то, что я прямо сейчас:
var b = new CustomBinding();
var sec = (AsymmetricSecurityBindingElement)SecurityBindingElement.CreateMutualCertificateBindingElement(MessageSecurityVersion.WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10);
UserNameSecurityTokenParameters tokenParamenters = new UserNameSecurityTokenParameters();
tokenParamenters.InclusionMode = SecurityTokenInclusionMode.AlwaysToRecipient;
tokenParamenters.RequireDerivedKeys = false;
b.Elements.Add(sec);
b.Elements.Add(new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8));
b.Elements.Add(new HttpsTransportBindingElement());
WSClient svc = new WSClient(b, new EndpointAddress(new Uri("https://serviceurl.com/SoapWS"), new DnsEndpointIdentity("CertificateIdentity"), new AddressHeaderCollection()));
svc.ClientCredentials.UserName.UserName = "username";
svc.ClientCredentials.UserName.Password = "password";
svc.ClientCredentials.ClientCertificate.Certificate = new X509Certificate2("Certificate.p12", "password");
svc.ClientCredentials.ServiceCertificate.DefaultCertificate = new X509Certificate2("Certificate.p12", "password");
svc.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None;
string resp = svc.DoSomething();
Хотя это, кажется, подписание сообщение с сертификатом (не был в состоянии полностью проверить), базовая аутентификация часть не происходит. Ответ сервера:
HTTP-запрос неавторизован с использованием схемы аутентификации клиента «Анонимный». Аутентификационный заголовок, полученный с сервера, был «Основное realm =» realm ».
Любая информация о том, как я могу получить эту привязку для аутентификации через транспорт с помощью аутентификации BASIC, будет очень полезной. Заранее спасибо.
PS: обратите внимание, что у меня нет контроля над веб-службой, с которой я пытаюсь общаться.
Спасибо! это было полезно. Я действительно получаю новую ошибку, которая не похожа на то, что она связана с аутентификацией BASIC: «Процессор безопасности не смог найти заголовок безопасности в сообщении». Я думаю, это означает, что сообщение не подписано правильно, знаете ли вы, что я могу пропустить? –
вам нужно получить образец рабочего сообщения и сравнить его с тем, который вы отправляете –
Хорошо, он работает сейчас. Проблема заключалась в том, что я получил ошибку с сервера и не был обеспечен. Мне просто пришлось добавить одну строку кода: 'sec.EnableUnsecuredResponse = true;' Теперь все работает нормально, спасибо. –