我有一些自我托管的WCF服务使用CustomBinding在特定端口上的HTTP协议。 我使用BinaryMessageEncodingBindingElement和HttpTransportBindingElement到目前为止没有问题。自我托管WCF自定义绑定,二进制消息,HTTPS传输无证
现在我需要通过使用HTTPS但没有证书来保护更多。我切换到HttpsTransportBindingElement并将RequireClientCertificate设置为false。
我没有证书安装在该端口上。我通过运行“netsh http show sslcert”进行检查。
我也得到遵循的错误,当我尝试我的服务添加到一个WPF应用程序(的Chrome浏览我得到“无法显示此网页提供”):
出现错误下载' https://开头本地主机:8080/myhost的/ myservice.svc”。
底层连接已关闭:发送时发生意外错误。
无法从传输连接读取数据:现有连接被远程主机强制关闭。
远程主机强制关闭现有连接
元数据包含无法解析的引用:'https:// localhost:8080/myhost/myservice.svc'。
将HTTP请求设置为“https:// localhost:8080/myhost/myservice.svc”时发生错误。
这可能是由于在HTTPS情况下服务器证书没有用HTTP.SYS正确配置。
这也可能是由于客户端与服务器之间的安全绑定不匹配造成的。
底层连接已关闭:发送时发生意外错误。
无法从传输连接读取数据:现有连接被远程主机强制关闭。
远程主机强制关闭现有连接
如果服务在当前解决方案中已定义,请尝试构建解决方案并再次添加服务参考。
这里去我的绑定:
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是假的,我的服务就是访问通过浏览器和WPF项目中的引用。
所以,我没有直接询问,所以我第一次请求帮助后,你的所有帮助。我错过了什么?因为它不是在IIS下托管的,所以我仍然需要证书才能在服务器端为特定端口进行安装。
先谢谢你们!如果有人已经回答了这种情况,我很抱歉没有找到它...
证书用于对方的身份验证,所以没有证书(或类似的身份验证机制),您的通信会受到中间人攻击。另外我怀疑WCF支持无证书SSL机制(SRP,PSK等)。可以在WCF中使用自签名证书,这已在SO上多次讨论过。 – 2012-07-13 14:35:27
如果没有证书,则无法使用HTTPS。 – 2012-07-13 21:59:21
所以就像我猜到的,我只需要为服务器端创建一个自签名证书,并使用netsh命令将其绑定到端口。 – Frankidoze 2012-07-17 10:56:20