9

私はこの1週間、このブラストされたWCFサービスの構成に苦労してきましたが、ドキュメントにもかかわらず、私がやろうとしていることは不可能だと思うようになり始めています。

簡単に言うと、WCFサービスにクライアント証明書(サーバーが証明書ストアに持つ)を要求し、System.ServiceModel.ServiceSecurityContextを使用してそのIDにアクセスするようにしたいのです。さらに、これはトランスポートセキュリティを使用する必要があります。

これが私のサーバー構成です:

<system.serviceModel>
    <services>
      <service behaviorConfiguration="requireCertificate" name="Server.CXPClient">
        <endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsHttpEndpointBinding" name="wsHttpEndpoint" contract="PartnerComm.ContentXpert.Server.ICXPClient" />
        <endpoint address="mex" binding="wsHttpBinding" bindingConfiguration="wsHttpEndpointBinding" name="mexEndpoint" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="https://localhost:8371/Design_Time_Addresses/Server/CXPClient/" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="requireCertificate">
          <serviceMetadata httpsGetEnabled="true" />
          <serviceCredentials>
            <serviceCertificate findValue="CyberdyneIndustries" storeLocation="LocalMachine" storeName="TrustedPeople" x509FindType="FindBySubjectName"/>
            <clientCertificate>
              <authentication certificateValidationMode="ChainTrust" trustedStoreLocation="LocalMachine" />
            </clientCertificate>
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <wsHttpBinding>
        <binding name="wsHttpEndpointBinding" maxBufferPoolSize="5242880" maxReceivedMessageSize="5242880">
          <readerQuotas maxDepth="32" maxStringContentLength="5242880" maxArrayLength="1073741824" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <security mode="Transport">
            <transport clientCredentialType="Certificate" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
  </system.serviceModel>

これが私のクライアント設定です:

  <system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="wsHttpEndpoint" closeTimeout="00:01:00" openTimeout="00:01:00"
          receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false"
          transactionFlow="false" hostNameComparisonMode="StrongWildcard"
          maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text"
          textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
            maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <reliableSession ordered="true" inactivityTimeout="00:10:00"
            enabled="false" />
          <security mode="Transport">
            <transport clientCredentialType="Certificate" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <client>
      <endpoint address="https://localhost:8371/Design_Time_Addresses/Server/CXPClient/"
        binding="wsHttpBinding" bindingConfiguration="wsHttpEndpoint" behaviorConfiguration="ClientCertificateBehavior"
        contract="ContentXPertServer.ICXPClient" name="wsHttpEndpoint" />
    </client>
    <behaviors>
      <endpointBehaviors>
        <behavior name="ClientCertificateBehavior">
          <clientCredentials>
            <clientCertificate x509FindType="FindBySubjectName" findValue="CyberdyneIndustries" storeLocation="LocalMachine" storeName="TrustedPeople" />
          </clientCredentials>
        </behavior>
      </endpointBehaviors>
    </behaviors>
  </system.serviceModel>

httpでsecuritymode='None'の場合、コードはすべて完全に機能しますが、もちろん、認証はなく、System.ServiceModel.ServiceSecurityContextには何もありません。これらすべての要素で数十のバリエーションを試しましたが、必然的に、「既存の接続がリモートホストによって強制的に閉じられました」という例外をスローするリクエストが発生します。

自己署名証明書「Cyber​​dyneIndustries」を使用しています。この証明書のCA証明書を信頼できるCAストアに追加しました。証明書を表示すると、証明書がチェックアウトされます。私はhttp名前空間管理の地獄を通り抜け、それらの問題も解決しました。WCFはこれを実際にはサポートしていないようです...私が間違っていると言ってください。

TIA。

4

4 に答える 4

2

最終的に、私はメッセージセキュリティを試して、それが状況に光を当てるかどうかを確認することにしました-それはそうしました、そして私は私の損失を減らしてそれを続けるつもりです。したがって、これに対する決定的な答えはありません。

ただし、メッセージセキュリティを実装すると、大きな問題が発生し、これがトランスポートセキュリティの問題の原因である可能性があります。MSDNから毒に関するドキュメントがあります。

http://msdn.microsoft.com/en-us/library/ff650751.aspx

このページで、自己署名証明書を作成するコマンドは次のとおりです。

makecert -sk MyKeyName -iv RootCaClientTest.pvk -n "CN = tempClientcert" -ic RootCaClientTest.cer -sr currentuser -ss my -skysignature -pe

引数「署名」は、代わ​​りに「交換」である必要があります。すべての証明書を再生成すると、メッセージセキュリティが機能し始めました。これらすべてからの大きなポイントの1つは、トランスポートセキュリティを実装する場合は、最初にメッセージセキュリティを機能させることです。これは、システムから取得するエラーメッセージがはるかにわかりやすいためです。

于 2010-12-07T14:49:31.413 に答える
1

SSLハンドシェイクは成功しますか?SChannelロギングを有効にして、SSLレイヤーのトラブルシューティングを行います。この古いKB記事を参照してください:IISでSchannelイベントロギングを有効にする方法。はW2KおよびXPのKBですが、SChannelロギングを有効にする手順は同じであり、新しいシステムでも引き続き有効です。ロギングを有効にすると、SSLが証明書を拒否する理由を特定できます。

于 2010-12-07T02:33:51.087 に答える
1

私はこれが3歳であることを知っていますが、まだ興味があるかもしれない人のために...

私はWCF(特にセキュリティ)を学習している途中で、clientCredentialType = "Certificate"(および、これは問題に密接な関係はありませんでしたが、protectionLevel = "EncryptAndSign")。

サーバー側からも強制接続クローズエラーが発生しましたが、構成の1つが欠落していることがわかりました。現在、すべて機能しています。

これが私のサーバー側の設定です:

<configuration>
  <system.serviceModel>
    <services>
      <service name="MyNamespace.MyService" behaviorConfiguration="MyServiceBehavior">
        <endpoint address="net.tcp://localhost:9002/MyServer" binding="netTcpBinding" bindingConfiguration="TcpCertSecurity" contract="MyNamespace.IMyService" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="MyServiceBehavior">
          <serviceCredentials>
            <serviceCertificate findValue="MyServiceCert" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
            <clientCertificate>
              <authentication certificateValidationMode="PeerTrust"/>
            </clientCertificate>
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <netTcpBinding>
        <binding name="TcpCertSecurity">
          <security mode="Transport">
            <transport clientCredentialType="Certificate" protectionLevel="EncryptAndSign" />
          </security>
        </binding>
      </netTcpBinding>
    </bindings>
  </system.serviceModel>
</configuration>

そして私のクライアント側の構成:

<configuration>
  <system.serviceModel>
    <client>
      <endpoint address="net.tcp://localhost:9002/MyServer" binding="netTcpBinding"
          bindingConfiguration="TcpCertSecurity" contract="MyNamespace.IMyService"
          behaviorConfiguration="MyServiceBehavior">
        <identity>
          <dns value="MyServiceCert" />
        </identity>
      </endpoint>
    </client>
    <bindings>
      <netTcpBinding>
        <binding name="TcpCertSecurity">
          <security mode="Transport">
            <transport clientCredentialType="Certificate" protectionLevel="EncryptAndSign" />
          </security>
        </binding>
      </netTcpBinding>
    </bindings>
    <behaviors>
      <endpointBehaviors>
        <behavior name="MyServiceBehavior">
          <clientCredentials>
            <serviceCertificate>
              <authentication certificateValidationMode="PeerTrust" />
            </serviceCertificate>
            <clientCertificate findValue="MyServiceCert" storeLocation="LocalMachine" storeName="TrustedPeople" x509FindType="FindBySubjectName" />
          </clientCredentials>
        </behavior>
      </endpointBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

ここで説明する手法を使用して、サーバーの証明書チェーン(自己署名の信頼されたルート証明書+そのルートを使用して構築された証明書)を作成し、サーバーホストマシンの証明書ストアにルート証明書と子証明書の両方を保存しました。そして最後に、そのサーバー証明書と公開鍵をクライアントホストマシン(LocalMachine / TrustedPeople)の証明書ストアにインポートしました。

于 2014-11-03T22:33:53.497 に答える
0

WsHttpBindingは、トランスポートセキュリティの証明書認証をサポートします。

いくつか間違っている可能性があります。

  1. 両方の証明書をストアに追加しましたか?Cyber​​dyneIndustriesとあなたがそれに署名するために使用したCA?CAは「信頼されたルート証明機関」に属している必要があります

  2. また、私はこれをセルフホストで実行しましたが、VisualStudioDevサーバーでは実行していません。少なくともIISでサービスをホストするようにしてください。VSDevサーバーが証明書をサポートしているかどうかはわかりません。

  3. サービス認証をオフにしてみてください。したがって、クライアントはサービスを認証する必要はありません。これをアプリに含めるかどうかはわかりませんが、テストのためだけに、除外することができます

    <behavior name="ClientCertificateBehavior">
    <clientCredentials>
        <clientCertificate x509FindType="FindBySubjectName" findValue="CyberdyneIndustries" storeLocation="LocalMachine" storeName="TrustedPeople" />
        <serviceCertificate>
            <authentication certificateValidationMode="None"/>
        </serviceCertificate>
    </clientCredentials>
    

于 2010-12-07T01:32:05.857 に答える