У меня есть собственная служба WCF, которая публикует веб-API REST. Сервис настроен программно и в настоящее время корректно работает через HTTP.
Теперь мне нужно заставить его работать по HTTPS с аутентификацией на основе файла сертификата.
Я знаю, что предлагаемый способ сделать это - установить сертификат в хранилище сертификатов Windows на сервере, но в моих обстоятельствах этот способ невозможен.
Мне нужно загрузить сертификат из файла.
После некоторых перезапусков я написал свой код, но при попытке доступа к веб-службе выдается исключение System.ServiceModel.CommunicationException с сообщением:
Произошла ошибка при выполнении HTTP-запроса к ... Это может быть связано с тем, что сертификат сервера не настроен должным образом с HTTP.SYS в случае HTTPS. Это также может быть вызвано несоответствием привязки безопасности между клиентом и сервером.
Вот мой код для серверной части:
_host = new WebServiceHost(_hostedService, Uri);
//Configuring the webHttpBinding settings
var httpBinding = new WebHttpBinding();
httpBinding.Security.Mode = WebHttpSecurityMode.Transport;
httpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
httpBinding.SendTimeout = new TimeSpan(0, 5, 0);
httpBinding.MaxBufferSize = 2147483647;
httpBinding.MaxBufferPoolSize = 2147483647;
httpBinding.MaxReceivedMessageSize = 2147483647;
httpBinding.ReaderQuotas.MaxDepth = 2147483647;
httpBinding.ReaderQuotas.MaxStringContentLength = 2147483647;
httpBinding.ReaderQuotas.MaxArrayLength = 2147483647;
httpBinding.ReaderQuotas.MaxBytesPerRead = 2147483647;
httpBinding.ReaderQuotas.MaxNameTableCharCount = 2147483647;
//Add the endpoint with the webHttpBinding settings to the WebServiceHost configuration
_host.AddServiceEndpoint(typeof(IService), httpBinding, Uri);
ServiceDebugBehavior stp = _host.Description.Behaviors.Find<ServiceDebugBehavior>();
stp.HttpHelpPageEnabled = false;
ServiceBehaviorAttribute sba = _host.Description.Behaviors.Find<ServiceBehaviorAttribute>();
sba.InstanceContextMode = InstanceContextMode.Single;
ServiceMetadataBehavior smb = new ServiceMetadataBehavior() { HttpsGetEnabled = true };
_host.Description.Behaviors.Add(smb);
X509Certificate2 trustedCertificate = new X509Certificate2("certificate.pfx", "password");
_host.Credentials.ServiceCertificate.Certificate = trustedCertificate;
_host.Credentials.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
Вот мой код для клиентской стороны:
var httpBinding = new WebHttpBinding();
httpBinding.Security.Mode = WebHttpSecurityMode.Transport;
httpBinding.Security.Transport = new HttpTransportSecurity() { ClientCredentialType = HttpClientCredentialType.Certificate };
var httpUri = new Uri(String.Format("https://{0}:{1}", ipAddress, tcpPort));
var httpEndpoint = new EndpointAddress(httpUri);
var newFactory = new ChannelFactory<IService>(httpBinding, httpEndpoint);
newFactory.Endpoint.Behaviors.Add(new WebHttpBehavior());
X509Certificate2 trustedCertificate = new X509Certificate2("certificate.pfx", "password"); //SSL
newFactory.Credentials.ClientCertificate.Certificate = trustedCertificate;
var channel = newFactory.CreateChannel();
var response = channel.Ping("helo");
Исключение выдается на последней строке (channel.Ping ("helo")).
Мне нужно, чтобы он работал БЕЗ установки сертификата на сервер.
Большое спасибо.
Bye.