自托管WCF自定义绑定,二进制消息,HTTPS传输没有证书

时间:2012-07-13 14:26:44

标签: wcf https ssl-certificate custom-binding

我在特定端口上使用CustomBinding for HTTP协议有一些自托管的WCF服务。 到目前为止,我使用BinaryMessageEncodingBindingElement和HttpTransportBindingElement没有问题。

现在我需要通过使用HTTPS但没有证书来保证更多。我切换到HttpsTransportBindingElement并将RequireClientCertificate设置为false。

我没有在该端口上安装证书。我通过运行“netsh http show sslcert”来检查。

当我尝试将我的服务添加到WPF应用程序时出现跟随错误(使用Chrome浏览器我得到“此网页不可用”):


  

下载'https:// localhost:8080 / myhost / myservice.svc'时出错。
  底层连接已关闭:发送时发生意外错误。
  无法从传输连接读取数据:远程主机强行关闭现有连接   远程主机强制关闭现有连接   元数据包含无法解析的引用:'https:// localhost:8080 / myhost / myservice.svc'。
  向“https:// localhost:8080 / myhost / myservice.svc”发出HTTP请求时发生错误。
  这可能是由于在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为false时,WPF项目中的浏览器和引用都可以访问我的服务。

所以我在享受了这么长时间的帮助后第一次寻求帮助而不直接询问。我错过了什么?因为它不是在IIS下托管,我是否还需要一个仅在特定端口上安装在服务器端的证书?

提前谢谢你们!如果有人已经回答了这个案子,我很抱歉找不到它......

1 个答案:

答案 0 :(得分:0)

就像我猜想的那样,我只需要为服务器端创建一个自签名证书,并使用netsh命令将其绑定到端口。 客户端不需要证书就意味着没有CERT的准HTTPS。

注意:我在计算机上运行了它。我将尝试在真实环境中部署后更新此帖子,如果我必须解决任何错误。

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