2012-07-13 51 views
1

我有一些自我托管的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下托管的,所以我仍然需要证书才能在服务器端为特定端口进行安装。

先谢谢你们!如果有人已经回答了这种情况,我很抱歉没有找到它...

+1

证书用于对方的身份验证,所以没有证书(或类似的身份验证机制),您的通信会受到中间人攻击。另外我怀疑WCF支持无证书SSL机制(SRP,PSK等)。可以在WCF中使用自签名证书,这已在SO上多次讨论过。 – 2012-07-13 14:35:27

+0

如果没有证书,则无法使用HTTPS。 – 2012-07-13 21:59:21

+0

所以就像我猜到的,我只需要为服务器端创建一个自签名证书,并使用netsh命令将其绑定到端口。 – Frankidoze 2012-07-17 10:56:20

回答

0

所以就像我猜测我只需要为服务器端创建一个自签名证书,并将其绑定到端口netsh命令。 在客户端没有证书需要准HTTPS WITHOUT CERT。

注意:我已经在我的电脑上工作了。我会尝试在真实环境中部署后更新此帖,如果我必须解决任何错误。

而且我知道在某些时候我们会在客户端获得完整的证书。 一石一石。