クライアントのセキュリティ保護
Windows Communication Foundation (WCF) では、クライアントのセキュリティ要件がサービスによって決定されます。 つまり、使用するセキュリティ モード、およびクライアントが資格情報を提供するかどうかは、サービスによって指定されます。 そのため、クライアントをセキュリティで保護するプロセスは、サービスから取得したメタデータ (公開されている場合) を使用してクライアントを構築するという簡単なものになります。 クライアントを構成する方法は、メタデータによって指定されます。 クライアントが資格情報を提供することをサービスが要求する場合、要件に適した資格情報を取得する必要があります。 ここでは、このプロセスについて詳しく説明します。 セキュリティで保護されたサービスの作成の詳細については、「サービスのセキュリティ保護」を参照してください。
サービスによるセキュリティの指定
既定では、WCF バインディングのセキュリティ機能は有効になっています (BasicHttpBinding を除く)。そのため、サービスが WCF を使用して作成されている場合、認証、機密性、および整合性を確実にするセキュリティが実装される可能性が高くなります。 この場合、サービスが提供するメタデータによって、セキュリティで保護された通信チャネルの確立に必要なものが示されます。 サービス メタデータにセキュリティ要件がまったく含まれていない場合には、サービスでセキュリティ スキーム (SSL (Secure Sockets Layer) over HTTP など) を強制する方法はありません。 ただし、サービスがクライアントに資格情報の提供を求める場合は、クライアントの開発者、展開担当者、または管理者は、クライアントがサービスに対して認証を受けるときに実際に使用する資格情報を提供する必要があります。
メタデータの取得
クライアントを作成する場合、最初の手順はクライアントが通信を行うサービスからメタデータを取得することです。 これは、次の 2 つの方法で行うことができます。 サービスにより MEX (Metadata Exchange) エンドポイントが公開されているか、HTTP または HTTPS 上でメタデータが使用可能になっている場合は、ServiceModel メタデータ ユーティリティ ツール (Svcutil.exe) を使用してメタデータをダウンロードできます。このツールは、クライアントのコード ファイルと構成ファイルの両方を生成します (ツールの使用の詳細については、「WCF クライアントを使用したサービスへのアクセス」を参照してください)。サービスにより MEX エンドポイントが公開されておらず、かつ HTTP または HTTPS 上でメタデータが使用可能になっていない場合は、サービス作成者に連絡して、セキュリティ要件とメタデータについて記述したドキュメントを入手する必要があります。
重要
メタデータが信頼されたソースのものであり、改ざんされていないことを確認することをお勧めします。 HTTP プロトコルを使用して取得したメタデータはクリア テキストで送信されるため、改ざんされるおそれがあります。 サービスで HttpsGetEnabled プロパティおよび HttpsGetUrl プロパティを使用している場合は、サービス作成者から提供された URL で、HTTPS プロトコルを使用してデータをダウンロードします。
セキュリティの検証
メタデータのソースは、信頼されたソースと信頼関係のないソースの 2 つに大きく分けられます。 ソースを信頼しており、そのソースのセキュリティで保護された MEX エンドポイントからクライアント コードとその他のメタデータをダウンロードしている場合、何の懸念もなく、クライアントをビルドし、適切な資格情報を提供して実行できます。
ただし、ほとんど未知のソースからクライアントとメタデータをダウンロードする場合は、コードで使用しているセキュリティ対策を検証する必要があります。 たとえば、サービスにより (最低でも) 機密性と整合性とが要求されていない場合は、個人情報や財務情報を送信するクライアントを作成するようなことは絶対に避けてください。 この種の情報はサービスの所有者から見ることが可能なので、この種の情報の開示を行ってもよいと判断できる程度にはサービスの所有者を信頼できる必要があります。
したがって、信頼できないソースから受け取ったコードとメタデータを使用する場合には、それがこちらの必要とするセキュリティ レベルを満たしていることを確認する必要があります。
クライアント資格情報の設定
クライアントへの資格情報の設定には、次の 2 つの手順があります。
サービスが必要とする "クライアント資格情報の種類" を決定します。 これは、2 つある方法のどちらかによって行います。 1 つ目の方法として、サービス作成者からドキュメントを入手している場合は、このドキュメントにサービスが要求するクライアント資格情報の種類が示されています (クライアント資格情報の種類が指定されている場合)。 2 番目の方法は Svcutil.exe ツールによって作成された構成ファイルしかない場合で、個々のバインディングを調べることで必要な資格情報の種類を特定できます。
実際のクライアント資格情報を指定します。 実際のクライアント資格情報は、資格情報の種類と区別するために、"クライアント資格情報の値" と呼ばれます。 たとえば、クライアント資格情報の種類として証明書が指定されている場合、サービスが信頼する証明機関によって発行された X.509 証明書を指定する必要があります。
クライアント資格情報の種類の特定
Svcutil.exe ツールによって生成された構成ファイルがある場合は、<bindings> セクションを調べて、必要とされるクライアント資格情報の種類を確認します。 このセクション内には、セキュリティ要件を指定するバインド要素があります。 具体的には、各バインディングの <security> 要素を調べます。 この要素には mode
属性が含まれており、3 つの値のいずれか (Message
、Transport
、または TransportWithMessageCredential
) に設定できます。 この属性の値によってモードが決定され、このモードによってどの子要素が有効なのかが決定されます。
<security>
要素には、<transport>
または <message>
要素のいずれか、あるいはその両方を含めることができます。 セキュリティ モードと一致する要素が有効な要素です。 たとえば、次のコードでは、セキュリティ モードを "Message"
、<message>
要素のクライアント資格情報の種類を "Certificate"
に指定しています。 この場合、<transport>
要素は無視できます。 ただし、<message>
要素で X.509 証明書を提示する必要があることが指定されています。
<wsHttpBinding>
<binding name="WSHttpBinding_ICalculator">
<security mode="Message">
<transport clientCredentialType="Windows"
realm="" />
<message clientCredentialType="Certificate"
negotiateServiceCredential="true"
algorithmSuite="Default"
establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
次の例に示すように、clientCredentialType
属性が "Windows"
に設定されている場合は、実際の資格情報の値を指定する必要はありません。 これは、Windows 統合セキュリティでは、クライアントを実行しているユーザーの実際の資格情報 (Kerberos トークン) が提供されるためです。
<security mode="Message">
<transport clientCredentialType="Windows "
realm="" />
</security>
クライアント資格情報の値の設定
クライアントが資格情報を提供する必要があると特定された場合は、クライアントを構成する適切なメソッドを使用します。 たとえば、クライアント証明書を設定するには、SetCertificate メソッドを使用します。
X.509 証明書は広く使用されている資格情報の形式です。 資格情報は次の 2 つの方法で提供できます。
- クライアント コードで (
SetCertificate
メソッドを使用して) プログラミングする方法。
クライアントの構成ファイルに <behaviors> セクションを追加し、clientCredentials
要素を使用する方法 (以下に示します)。
コードでの <clientCredentials> 値の設定
コードで <clientCredentials> 値を設定するには、ClientBase<TChannel> クラスの ClientCredentials プロパティにアクセスする必要があります。 このプロパティは、次の表に示すように、各種の資格情報の種類にアクセスできる ClientCredentials オブジェクトを返します。
ClientCredential プロパティ | 説明 | Notes |
---|---|---|
ClientCertificate | X509CertificateInitiatorClientCredential を返します | クライアントがサービスに対して自身を認証するために提供する X.509 証明書を表します。 |
HttpDigest | HttpDigestClientCredential を返します | HTTP ダイジェスト資格情報を表します。 この資格情報は、ユーザー名とパスワードのハッシュです。 |
IssuedToken | IssuedTokenClientCredential を返します | フェデレーション シナリオで通常使用される、セキュリティ トークン サービスによって発行されるカスタム セキュリティ トークンを表します。 |
Peer | PeerCredential を返します | Windows ドメインのピア メッシュに参加するためのピア資格情報を表します。 |
ServiceCertificate | X509CertificateRecipientClientCredential を返します | 帯域外ネゴシエーションでサービスによって提供される X.509 証明書を表します。 |
UserName | UserNamePasswordClientCredential を返します | ユーザー名とパスワードのペアを表します。 |
Windows | WindowsClientCredential を返します | Windows クライアントの資格情報 (Kerberos 資格情報) を表します。 このクラスのプロパティは読み取り専用です。 |
構成での <clientCredentials> 値の設定
エンドポイントの動作を使用して、<clientCredentials> 要素の子要素として資格情報の値を指定します。 使用される要素は、クライアントの資格情報の種類によって異なります。 たとえば、次の例では、<<clientCertificate> を使用して X.509 証明書を設定する構成を示しています。
<configuration>
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="myEndpointBehavior">
<clientCredentials>
<clientCertificate findvalue="myMachineName"
storeLocation="Current" X509FindType="FindBySubjectName" />
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
構成でクライアント資格情報を設定するには、構成ファイルに <endpointBehaviors> 要素を追加します。 さらに、次の例に示すように、<client> 要素の <endpoint> の behaviorConfiguration
属性を使用して、追加した動作要素をサービスのエンドポイントにリンクする必要があります。 behaviorConfiguration
属性の値は、動作の name
属性の値と一致する必要があります。
<configuration>
<system.serviceModel>
<client>
<endpoint address="http://localhost/servicemodelsamples/service.svc"
binding="wsHttpBinding"
bindingConfiguration="Binding1"
behaviorConfiguration="myEndpointBehavior"
contract="Microsoft.ServiceModel.Samples.ICalculator" />
</client>
</system.serviceModel>
</configuration>
Note
クライアント資格情報の値の中には、アプリケーション構成ファイルを使用して設定できないものがあります (ユーザー名とパスワードや、Windows ユーザーとパスワードの値など)。 このような資格情報の値は、コードでのみ指定できます。
クライアント資格情報の設定の詳細については、「方法: クライアントの資格情報の値を指定する」を参照してください。
Note
ClientCredentialType
は、次のサンプル構成に示すように、 SecurityMode
が "TransportWithMessageCredential"
に設定されている場合は無視されます。
<wsHttpBinding>
<binding name="PingBinding">
<security mode="TransportWithMessageCredential" >
<message clientCredentialType="UserName"
establishSecurityContext="false"
negotiateServiceCredential="false" />
<transport clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>