У меня есть несколько собственных служб WCF, использующих протокол CustomBinding для HTTP на определенном порту. Я использую BinaryMessageEncodingBindingElement и HttpTransportBindingElement до сих пор без проблем.
Теперь мне нужно немного обезопасить себя, используя HTTPS, но без сертификата. Я переключился на HttpsTransportBindingElement и установил для RequireClientCertificate значение false.
У меня нет сертификата, установленного на этом порту. Я проверил, запустив «netsh http show sslcert».
И я получаю следующую ошибку, когда пытаюсь добавить свою службу в приложение WPF (просматривая Chrome, я получаю «Эта веб-страница недоступна»):
При загрузке https://localhost:8080/myhost/myservice.svc произошла ошибка.
Базовое соединение было закрыто: при отправке произошла непредвиденная ошибка.
Невозможно прочитать данные из транспортного соединения: существующее соединение было принудительно закрыто удаленным узлом.
Существующее соединение было принудительно закрыто удаленным узлом.
Метаданные содержат ссылку, которую невозможно разрешить. : 'https://localhost:8080/myhost/myservice.svc'.
Произошла ошибка при отправке HTTP-запроса к «https://localhost:8080/myhost/myservice.svc».
Это может быть связано с тем, что сертификат сервера неправильно настроен с HTTP.SYS в случае HTTPS.
Это также может быть вызвано несоответствием привязки безопасности между клиентом и сервером.
Базовое соединение было закрыто: при отправке произошла непредвиденная ошибка.
Невозможно прочитать данные из транспортного соединения: существующее соединение было принудительно закрыто удаленным узлом.
Существующее соединение было принудительно закрыто удаленным узлом.
Если служба определена в текущем решении, попробуйте создать решение и снова добавить ссылку на службу.
Вот моя привязка:
private System.ServiceModel.Channels.Binding GetHttpBinding(String pName)
{
System.ServiceModel.Channels.BindingElementCollection elements = new System.ServiceModel.Channels.BindingElementCollection();
System.ServiceModel.Channels.BinaryMessageEncodingBindingElement binaryMessageEncoding = new System.ServiceModel.Channels.BinaryMessageEncodingBindingElement();
binaryMessageEncoding.MessageVersion = System.ServiceModel.Channels.MessageVersion.Default;
binaryMessageEncoding.ReaderQuotas.MaxArrayLength = this._maxArrayLength;
binaryMessageEncoding.ReaderQuotas.MaxBytesPerRead = this._maxBytesPerRead;
binaryMessageEncoding.ReaderQuotas.MaxDepth = this._maxDepth;
binaryMessageEncoding.ReaderQuotas.MaxNameTableCharCount = this._maxNameTableCharCount;
binaryMessageEncoding.ReaderQuotas.MaxStringContentLength = this._maxStringContentLength;
elements.Add(binaryMessageEncoding);
if (this._applyHttps)
{
System.ServiceModel.Channels.HttpsTransportBindingElement transport = new System.ServiceModel.Channels.HttpsTransportBindingElement()
{
MaxBufferSize = this._maxBufferSize,
MaxReceivedMessageSize = this._maxReceivedMessageSize,
AllowCookies = false,
BypassProxyOnLocal = false,
HostNameComparisonMode = HostNameComparisonMode.StrongWildcard,
MaxBufferPoolSize = this._maxBufferPoolSize,
TransferMode = TransferMode.Buffered,
UseDefaultWebProxy = true,
ProxyAddress = null,
RequireClientCertificate = false
};
elements.Add(transport);
}
else
{
System.ServiceModel.Channels.HttpTransportBindingElement transport = new System.ServiceModel.Channels.HttpTransportBindingElement()
{
MaxBufferSize = this._maxBufferSize,
MaxReceivedMessageSize = this._maxReceivedMessageSize,
};
elements.Add(transport);
}
System.ServiceModel.Channels.CustomBinding custB = new System.ServiceModel.Channels.CustomBinding(elements);
custB.Name = pName;
custB.SendTimeout = new TimeSpan(0, 2, 0);
return custB;
}
И я настраиваю узел службы с помощью этого метода:
private void ConfigureBinaryService(ServiceHost pHost, Type pType, String pServiceName)
{
pHost.AddServiceEndpoint(pType, this.GetHttpBinding(pType.Name), String.Empty);
pHost.AddServiceEndpoint(pType, this.GetNetTcpBinding(pType.Name), String.Empty);
pHost.Description.Endpoints[0].Name = pType.Name + "_BasicBin";
pHost.Description.Endpoints[1].Name = pType.Name + "_TCP";
pHost.OpenTimeout = new TimeSpan(0, 2, 0);
pHost.CloseTimeout = new TimeSpan(0, 2, 0);
System.ServiceModel.Description.ServiceMetadataBehavior metadataBehavior = pHost.Description.Behaviors.Find<System.ServiceModel.Description.ServiceMetadataBehavior>();
if (metadataBehavior == null)
{
metadataBehavior = new System.ServiceModel.Description.ServiceMetadataBehavior();
pHost.Description.Behaviors.Add(metadataBehavior);
}
if (this._applyHttps)
metadataBehavior.HttpsGetEnabled = true;
else
metadataBehavior.HttpGetEnabled = true;
metadataBehavior.MetadataExporter.PolicyVersion = System.ServiceModel.Description.PolicyVersion.Policy15;
if (this._applyHttps)
pHost.AddServiceEndpoint(System.ServiceModel.Description.ServiceMetadataBehavior.MexContractName
, System.ServiceModel.Description.MetadataExchangeBindings.CreateMexHttpsBinding(), "mex");
else
pHost.AddServiceEndpoint(System.ServiceModel.Description.ServiceMetadataBehavior.MexContractName
, System.ServiceModel.Description.MetadataExchangeBindings.CreateMexHttpBinding(), "mex");
pHost.AddServiceEndpoint(System.ServiceModel.Description.ServiceMetadataBehavior.MexContractName
, System.ServiceModel.Description.MetadataExchangeBindings.CreateMexTcpBinding(), this._NetTcpComm + @"/" + pServiceName + @"/mex");
pHost.Description.Endpoints[2].Name = pType.Name + "_mex_BasicBin";
pHost.Description.Endpoints[3].Name = pType.Name + "_mex_TCP";
foreach (var item in pHost.Description.Endpoints[0].Contract.Operations)
item.Behaviors.Find<System.ServiceModel.Description.DataContractSerializerOperationBehavior>().MaxItemsInObjectGraph = System.Int32.MaxValue;
foreach (var item in pHost.Description.Endpoints[1].Contract.Operations)
item.Behaviors.Find<System.ServiceModel.Description.DataContractSerializerOperationBehavior>().MaxItemsInObjectGraph = System.Int32.MaxValue;
System.ServiceModel.Description.ServiceDebugBehavior debugBehavior =
pHost.Description.Behaviors.Find<System.ServiceModel.Description.ServiceDebugBehavior>();
if (debugBehavior == null)
{
debugBehavior = new System.ServiceModel.Description.ServiceDebugBehavior();
pHost.Description.Behaviors.Add(debugBehavior);
}
debugBehavior.IncludeExceptionDetailInFaults = true;
}
Когда this._applyHttps имеет значение false, мой сервис доступен как через браузер, так и по ссылке в проекте WPF.
Поэтому я впервые прошу о помощи после того, как так долго наслаждался всей вашей помощью, не спрашивая напрямую. Что мне не хватает? Поскольку он не размещен в IIS, мне все еще нужен сертификат для установки на стороне сервера только для определенного порта?
Спасибо, ребята, заранее! И если кто-то уже ответил на этот случай, я извиняюсь, что не нашел его...