WCF, REST, SSL, клиент, проверка собственного сертификата - PullRequest
2 голосов
/ 21 января 2011

У меня есть конкретная проблема, которую я не могу решить.Позвольте мне объяснить подробно.Я новичок в этой технологии, поэтому я могу использовать некоторые неправильные термины.Пожалуйста, исправьте и объясните или попросите объяснения, если вы не понимаете.Я создаю собственный сервер WCF REST, размещенный в приложении WPF.Он использует https, SLL с WebHttpSecurityMode.Transport.Я использую свой собственный сгенерированный сертификат.Я хотел бы создать клиент WinForms, который будет использовать этот сервис.Формат ответа сервера - JSON.Я хотел бы проверить сертификат на клиенте с помощью моего пользовательского валидатора, унаследованного от X509CertificateValidator.

Это мой код на стороне сервера.Я использую пользовательский валидатор имени пользователя, который работает нормально.Я настроил сертификат в диспетчере IIS на своем компьютере для веб-сайта по умолчанию> Привязки, где я сгенерировал сертификат (Windows 7).

WebServiceHost sh = new WebServiceHost(typeof(ReachService)); 
string uri = "https://localhost:9000/Service"; 
WebHttpBinding wb = new WebHttpBinding(); 
wb.Security.Mode = WebHttpSecurityMode.Transport; 
wb.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
sh.AddServiceEndpoint(typeof(IReachService), wb, uri);
sh.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new CustomUserNameValidator();
sh.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom;

sh.Open();

, и это мой код клиента

Uri uri = new Uri("https://localhost:9000/Service");
WebChannelFactory<ReachService> cf = new WebChannelFactory<IReachService>(uri);
WebHttpBinding wb = cf.Endpoint.Binding as WebHttpBinding;
wb.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
wb.Security.Mode = WebHttpSecurityMode.Transport;
cf.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.Custom;
cf.Credentials.ServiceCertificate.Authentication.CustomCertificateValidator = new CustomCertificateValidator("PL2"); // this is the name that issued the certificate
cf.Credentials.UserName.UserName = "user1"; 
cf.Credentials.UserName.Password = "user1";
IReachService service = cf.CreateChannel();
try
{
  CustomersList auth = service.GetCustomers();
}
catch (Exception ex)
{
   throw new Exception(ex.Message);
}

при вызове сервиса. GetCustomers () Я получаю: Не удалось установить доверительные отношения для безопасного канала SSL / TLS с полномочиями «localhost: 9000».Сообщение InnerException: базовое соединение было закрыто: не удалось установить доверительные отношения для безопасного канала SSL / TLS.InnerException Message: удаленный сертификат недействителен в соответствии с процедурой проверки.

Сервер работает нормально, когда я тестирую в браузере.Но клиентский код неверен, потому что он не переходит в пользовательский класс проверки сертификата.И этот класс такой же, как в примере MSDN на http://msdn.microsoft.com/en-us/library/system.identitymodel.selectors.x509certificatevalidator.aspx.

Может кто-нибудь сказать мне, где я ошибаюсь с этим подходом?

Если вам нужна дополнительная информация, пожалуйста, спросите.

Спасибо

Ответы [ 3 ]

1 голос
/ 21 января 2011

Похоже, что проблема возникает, потому что сертификат был выдан для другого имени хоста.Вы можете проверить это (и настроить при необходимости), предоставив пользовательский ServicePointManager.ServerCertificateValidationCallback.

1 голос
/ 27 апреля 2011

// не используйте HttpWebRequest - вы теряете все строго типизированные методы и контракты данных!

// код для создания канала и вызова метода:

SetCertPolicy(); 
var cf1 = new WebChannelFactory<TService>(new Uri(remoteServiceAddressSecure));
var service = cf1.CreateChannel();
sevice.DoMethod();

protected static void SetCertPolicy()
        {
            ServicePointManager.ServerCertificateValidationCallback += RemoteCertValidate;
        }

private static bool RemoteCertValidate(object sender, X509Certificate cert, X509Chain chain,
                SslPolicyErrors error)
        {
            // trust any cert!!!
            return true;
        }
0 голосов
/ 21 января 2011

Если вы хотите использовать WCF на клиенте, то не используйте WebHttpBinding, придерживайтесь SOAP, это будет работать намного лучше.
Однако, если вы хотите использовать стандартный HTTP-клиент, например, WebClient или HttpWebRequest или HttpClient V.prototype или HttpClient V.Next затем придерживаться webHttpBinding.

Приносим извинения за то, что не обратились к вашему прямому вопросу, но вы, вероятно, столкнетесь с большим количеством проблем, потому что вы используете привязку, предназначенную для того, чтобы сделать службы WCF доступными для платформ, отличных от WCF, но затем используете WCF, чтобы попытаться получить к ней доступ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...