自托管WCF自定义绑定、二进制消息、无证书HTTPS传输
我有一些在特定端口上使用CustomBinding for HTTP协议的自托管WCF服务。 到目前为止,我使用BinaryMessageEncodingBindingElement和HttpTransportBindingElement没有问题 现在我需要通过使用HTTPS获得更多的安全性,但没有证书。我切换到HttpsTransportBindingElement并将RequireClientCertificate设置为false 我在那个端口上没有安装证书。我通过运行“netshhttpshowslcert”进行了检查 当我尝试将我的服务添加到WPF应用程序时(使用Chrome浏览时,我得到“此网页不可用”):自托管WCF自定义绑定、二进制消息、无证书HTTPS传输,wcf,https,ssl-certificate,custom-binding,Wcf,Https,Ssl Certificate,Custom Binding,我有一些在特定端口上使用CustomBinding for HTTP协议的自托管WCF服务。 到目前为止,我使用BinaryMessageEncodingBindingElement和HttpTransportBindingElement没有问题 现在我需要通过使用HTTPS获得更多的安全性,但没有证书。我切换到HttpsTransportBindingElement并将RequireClientCertificate设置为false 我在那个端口上没有安装证书。我通过运行“netshhttps
下载“”时出错https://localhost: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;
}
private void ConfigureBinaryService(ServiceHost pHost,类型pType,字符串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=新的时间跨度(0,2,0);
pHost.CloseTimeout=新的时间跨度(0,2,0);
System.ServiceModel.Description.ServiceMetadataBehavior=pHost.Description.Behaviors.Find();
if(metadataBehavior==null)
{
metadataBehavior=new System.ServiceModel.Description.ServiceMetadataBehavior();
pHost.Description.Behaviors.Add(metadataBehavior);
}
如果(本应用程序)
metadataBehavior.HttpsGetEnabled=true;
其他的
metadataBehavior.HttpGetEnabled=true;
metadataBehavior.MetadataExporter.PolicyVersion=System.ServiceModel.Description.PolicyVersion.Policy15;
如果(本应用程序)
pHost.AddServiceEndpoint(System.ServiceModel.Description.ServiceMetadataBehavior.MexContractName
,System.ServiceModel.Description.MetadataExchangeBindings.CreateMexHttpsBinding(),“mex”);
其他的
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+“\u mex\u BasicBin”;
pHost.Description.Endpoints[3]。Name=pType.Name+“\u-mex\u-TCP”;
foreach(pHost.Description.Endpoints[0].Contract.Operations中的变量项)
item.Behaviors.Find().MaxItemsInObjectGraph=System.Int32.MaxValue;
foreach(pHost.Description.Endpoints[1].Contract.Operations中的变量项)
item.Behaviors.Find().MaxItemsInObjectGraph=System.Int32.MaxValue;
System.ServiceModel.Description.ServiceDebugBehavior调试行为=
pHost.Description.Behaviors.Find();
if(debugBehavior==null)
{
debugBehavior=新系统.ServiceModel.Description.ServiceDebugBehavior();
pHost.Description.Behaviors.Add(debugBehavior);
}
debugBehavior.IncludeExceptionDetailInFaults=true;
}
当此._applyhtps为false时,我的服务可以通过浏览器和WPF项目中的引用访问
在享受了你这么长时间的帮助后,我第一次请求帮助,而不是直接请求。我错过了什么?由于它不在IIS下托管,我是否仍需要在服务器端仅为特定端口安装证书
提前谢谢大家!如果有人已经回答了这个问题,我很抱歉没有找到它…就像我猜的那样,我只需要为服务器端创建一个自签名证书,并使用netsh命令将其绑定到端口。 客户端不需要证书,这意味着没有证书的准HTTPS 注意:我让它在我的电脑上工作。一旦部署到真实环境中,如果我必须解决任何错误,我将尝试更新这篇文章 我知道在某个时候,我们会在客户端进行完全认证。
每次一块石头。证书用于另一方的身份验证,因此如果没有证书(或类似的身份验证机制),您的通信将受到中间人攻击。我还怀疑WCF是否支持无证书SSL机制(SRP、PSK等)。在WCF中使用自签名证书是可能的,这在这里已经讨论过很多次了。你不能使用HTTPS