3

ベンダーからデータを受信するためのベンダーの実装に基づいて、WCF サービスを開発しています。サーバー証明書を使用するクライアントで一方向SSLを使用するこのサービスの動作バージョンがあります。最近実装が変更されたため、ユーザー名とパスワードの代わりに証明書を使用してクライアントを認証する必要があります。

それらは Java で開発されており、私はクライアントや証明書の生成方法を制御できません。これらは WSHttpBinding をサポートしていないため、BasicHttpBinding を使用する必要があります。彼らの証明書は自己署名されており、残念ながら本番環境ではそのようになります。セキュリティのためにトランスポートを使用してみましたが、サーバー管理者によると、証明書がサーバーに適切にインストールされていました (IIS サーバーへのアクセス権がありません)。証明書は自己署名であるため、IIS に問題があったと思われるため、その実装から離れました。

多くの調査の結果、OperationContext.Current.ServiceSecurityContext.AuthorizationContext.ClaimSets[0]. これは私の最初の WCF サービスなので、正しくセットアップされていると思いますが、WCF テスト クライアントからテストすると次のエラーが発生しますThe private key is not present in the X.509 certificate。クライアントからベンダーテストを受けると、彼らは得ていますAn error occurred when verifying security for the message.

何かが正しく構成されていませんか? この実装はサポートされていますか?

サービス Web.Config:

<?xml version="1.0"?>
    <configuration>
        <system.serviceModel>
                 <behaviors>
                <serviceBehaviors>
                    <behavior name="FileReceiverServiceBehavior">
                        <useRequestHeadersForMetadataAddress/>
                        <serviceMetadata httpsGetEnabled="true"/>
                    </behavior>
                </serviceBehaviors>
            </behaviors>
            <bindings>
                <basicHttpBinding>
                    <binding name="FileReceiverServiceBinding">
                        <security mode="TransportWithMessageCredential">
                            <message clientCredentialType="Certificate"/>
                        </security>
                        <readerQuotas maxStringContentLength="2147483647"/>
                    </binding>
                </basicHttpBinding>
            </bindings>
            <services>
                <service behaviorConfiguration="FileReceiverServiceBehavior" name="FileReceiverService.FileReceiverService">
                    <endpoint address="" binding="basicHttpBinding" bindingConfiguration="FileReceiverServiceBinding" contract="FileReceiverServiceSoap" bindingNamespace="http://www.openuri.org/" />
                    <endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"/>
                </service>
            </services>
        </system.serviceModel>
    </configuration>

私のWCFテストクライアント構成:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <behaviors>
      <endpointBehaviors>
        <behavior name="test">
          <clientCredentials>
            <clientCertificate findValue="Users"
                               x509FindType="FindBySubjectName"
                               storeLocation="LocalMachine"
                               storeName="My"/>
          </clientCredentials>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <bindings>
      <basicHttpBinding>
        <binding name="BasicHttpBinding_FileReceiverServiceSoap" closeTimeout="00:01:00"
          openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
          allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
          maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
          messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
          useDefaultWebProxy="true">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
            maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <security mode="TransportWithMessageCredential">
            <transport clientCredentialType="None" proxyCredentialType="None"
              realm="" />
            <message clientCredentialType="Certificate" algorithmSuite="Default" />
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="https://mydomain.com/vendor/FileReceiverService.svc"
        binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_FileReceiverServiceSoap"
        contract="ServiceReference1.FileReceiverServiceSoap" name="BasicHttpBinding_FileReceiverServiceSoap" behaviorConfiguration="test" />
    </client>
  </system.serviceModel>
</configuration>

アップデート:

ベンダーから正しい証明書が送られてきました。これは、商用 CA によって発行された有効な証明書です。証明書をローカルで表示すると、信頼されたルートへのチェーンが表示され、ステータスが「OK」と表示されます。

使用security mode="Transport"transport clientCredentialType="Certificate"て取得した場合:クライアント認証スキーム「匿名」でHTTPリクエストが禁止されました

使用security mode="TransportWithMessageCredential"message clientCredentialType="Certificate"て取得した場合: 秘密鍵が X.509 証明書に存在しません。

Javaクライアントと相互運用できるように厳密にトランスポートを使用する必要があると思うので、「クライアント認証スキーム「匿名」でHTTPリクエストが禁止されました」というエラーに焦点を当てています。それは IIS 設定の問題ですか、それともサーバーに到達したときに証明書を正しく検証できないだけですか? 証明書は Trusted People にあり、クライアントcertificateValidationModeだけでなくPeerTrust、も試しました。どんな助けでも大歓迎です。ChainTrustPeerOrChainTrust

アップデート2:

これを元のサーバー構成に次のように変更し、テスト クライアントに合わせて変更することで、これを機能させることに重点を置いています。

<security mode="Transport">
  <transport clientCredentialType="Certificate"/>

私はまだ取得します: HTTP リクエストは、クライアント認証スキーム 'Anonymous' で禁止されていました。ここで、クライアント証明書がサーバーによって検証されなかったことを基本的に確認する説明を見つけました。サーバー管理者に IIS でこのアプリケーションを構成させ、証明書をインストールして正しく動作させるにはどうすればよいですか?

4

1 に答える 1

3

コメントでの長い議論の後、WCF での X.509 証明書への 9 つの簡単な手順の記事を紹介します。単なるリンクであることはわかっていますが、非常に長い記事です。

あなたの問題は、実際には、クライアントが認証できる証明書を持っていないことにあるようです。あなたが狙っているスキームでは、各クライアントはそれらを識別する秘密鍵を持っている必要があり、サーバー/サービスは署名を検証するために対応する公開鍵を持っている必要があります(少なくともキーストアにインストールされています)。

現在の設定では、各クライアントが信頼できるサーバーとしてサーバーの公開鍵を持っているようです。したがって、SSL経由で接続して暗号化することができ、クライアントはサーバーを信頼しますが、サーバーは実際にクライアントが誰であるかを知らないか、少なくともそれらを識別するものなしでは認証できません. ユーザー名とパスワードの以前の方法は、以前に識別された方法ですが、x.509 証明書では、ユーザー名とパスワードの組み合わせを持っていた各人は、認証を行うために秘密鍵を含む一意の証明書が必要になります。

次に、これらのユーザーを Windows/LDAP アカウントにマップして管理とアクセス制御を容易にするか、プライベート証明書を検証するためにカスタム バリデーター(場合によっては IIdentity、プリンシパル、およびサービス資格情報)を実装する必要があります。ユーザーを「ログイン」させます。

これが少しでもお役に立てば幸いです。 x509 カスタム認証と val に関するもう 1 つの例を次に示します。

編集: Update2 に対応して、IIS サイト/アプリケーションを SSL 設定で "IGNORE User Certificates" に設定してみて、別のエラーが発生するかどうかを確認してください。コードでASP 互換モードをオンにしていない場合、IIS は IIdentity を渡さず、IIS で何らかの認証方式を設定していない限り、何もしない可能性があります。これを無視するように設定すると、カスタムバリデーターをすばやくセットアップして、証明書が通過するのを確認できます。その上でチェーンを構築し、それらに対して何らかの認証を作成できます。

于 2012-10-29T16:24:35.610 に答える