1

特定のポートでHTTPプロトコルのCustomBindingを使用するセルフホストのWCFサービスがいくつかあります。これまでのところ、BinaryMessageEncodingBindingElementとHttpTransportBindingElementを問題なく使用しています。

次に、HTTPSを使用して、証明書を使用せずに、もう少しセキュリティを確保する必要があります。HttpsTransportBindingElementに切り替えて、RequireClientCertificateをfalseに設定しました。

そのポートに証明書がインストールされていません。「netshhttpshowsslcert」を実行して確認しました。

また、サービスをWPFアプリに追加しようとすると、フォローエラーが発生します(Chromeでブラウジングすると、「このWebページは利用できません」と表示されます)。


'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でホストされていないため、特定のポートに対してのみサーバー側にインストールするための証明書が必要ですか?

よろしくお願いします!そして、誰かがすでにこのケースに答えているなら、私はそれを見つけられなくてすみません...

4

1 に答える 1

0

したがって、私が推測したように、サーバー側のみの自己署名証明書を作成し、netshコマンドでポートにバインドする必要がありました。クライアント側で証明書は必要ありません。つまり、CERTなしの準HTTPSです。

注:コンピューターで動作させました。実際の環境にデプロイされたら、間違いに対処する必要がある場合は、この投稿を更新しようとします。

そして、ある時点で、クライアント側で完全な証明書を取得することを知っています。一度に1つの石。

于 2012-07-17T11:03:34.647 に答える