サービス ID と認証

サービスのエンドポイント ID は、サービスの Web サービス記述言語 (WSDL) から生成される値です。 この値は、すべてのクライアントに反映され、サービスの認証に使用されます。 クライアントがエンドポイントとの通信を開始し、サービスがクライアントに対して認証を行った後に、クライアントは、エンドポイント ID 値とエンドポイントの認証プロセスから返された実際の値を比較します。 この 2 つの値が一致した場合、クライアントは要求したサービス エンドポイントに接続していることを確認できます。 これは、悪質なサービスでホストされたエンドポイントにクライアントがリダイレクトされることを防いで、フィッシングから保護する役割を果たします。

ID の設定を示すサンプル アプリケーションについては、「サービス ID のサンプル」を参照してください。 エンドポイントとエンドポイント アドレスの詳細については、アドレスに関するページを参照してください。

Note

認証に NTLM (NT LanMan) を使用する場合、NTLM ではクライアントがサーバーを認証できないため、サービス ID はチェックされません。 NTLM はコンピューターが Windows ワークグループの一部である場合、または Kerberos 認証をサポートしていない古いバージョンの Windows が実行されている場合に使用されます。

サービスに対してメッセージを送信するためにクライアントがセキュリティで保護されたチャネルを開始すると、Windows Communication Foundation (WCF) インフラストラクチャはこのサービスを認証し、サービス ID がクライアントの使用するエンドポイント アドレスに指定された ID と一致する場合にのみメッセージを送信します。

ID の処理は、次の 2 段階から成ります。

  • デザイン時に、クライアント開発者は、(WSDL を通じて公開される) エンドポイントのメタデータでサービスの ID を確認します。

  • 実行時に、クライアント アプリケーションにより、メッセージをサービスに送信する前に、サービスのセキュリティ資格情報のクレームが確認されます。

クライアントでの ID の処理は、サービスでのクライアント認証と似ています。 セキュリティで保護されたサービスは、クライアントの資格情報が認証されるまでコードを実行しません。 同様に、クライアントは、サービスのメタデータによって事前に認識されている内容に基づいて、サービスの資格情報が認証されるまでメッセージを送信しません。

Identity クラスの EndpointAddress プロパティは、クライアントによって呼び出されるサービスの ID を表します。 サービスはこの Identity をサービスのメタデータ内に公開します。 クライアント開発者がサービス エンドポイントに対して ServiceModel メタデータ ユーティリティ ツール (Svcutil.exe) を実行すると、生成された構成にサービスの Identity プロパティの値が含められます。 WCF インフラストラクチャ (セキュリティが構成されている場合) は、サービスが指定された ID を所有しているかどうかを検査します。

重要

メタデータには、サービスに要求される ID が含まれています。したがって、安全な方法 (サービスの HTTPS エンドポイントを作成するなど) でサービス メタデータを公開することをお勧めします。 詳細については、「方法: メタデータ エンドポイントをセキュリティで保護する」を参照してください。

ID の種類

サービスが提供できる ID は 6 種類あります。 ID の各種類は、構成内の <identity> 要素に含めることのできる要素に対応します。 使用する ID の種類は、シナリオとサービスのセキュリティ要件によって異なります。 ID の各種類の説明を次の表に示します。

ID の種類 説明 一般的なシナリオ
ドメイン ネーム システム (DNS) この要素は X.509 証明書または Windows アカウントと一緒に使用します。 資格情報に指定されている DNS 名とこの要素で指定されている値とが比較されます。 DNS チェックを行うことにより、DNS 名またはサブジェクト名を含む証明書を使用できます。 同じ DNS 名またはサブジェクト名を使用して証明書が再発行された場合、ID 検査は引き続き有効になります。 証明書を再発行すると、新しい RSA キーが取得されますが、同じ DNS 名またはサブジェクト名が保持されます。 つまり、クライアントはサービスの ID 情報を更新する必要がありません。
証明書。 ClientCredentialType が Certificate に設定されている場合の既定値です。 この要素は、クライアントと比較するための Base64 でエンコードされた X.509 証明書の値を指定します。

サービスを認証するときの資格情報として CardSpace を使用する場合にも、この要素が使用されます。
この要素は、証明書の拇印の値に基づいて、認証を 1 つの証明書に制限します。 拇印の値は一意であるため、この制限によってより厳密な認証が可能になります。 同じサブジェクト名を使用して証明書が再発行された場合、証明書には新しい拇印が含まれることになるので注意が必要です。 つまり、新しい拇印が認識されていない場合、クライアントはサービスを検証できなくなります。 証明書の拇印の確認に関する詳細については、「方法: 証明書のサムプリントを取得する」を参照してください。
証明書参照 前述の証明書オプションと同じです。 ただし、この要素を使用すると、証明書の名前と証明書を取得するストアの場所を指定できます。 前述の証明書のシナリオと同じです。

利点は、証明書ストアの場所を変更できることです。
RSA この要素は、クライアントと比較するための RSA キーの値を指定します。 これは証明書オプションに似ていますが、証明書の拇印を使用するのではなく、証明書の RSA キーを使用します。 RSA チェックを行うと、証明書の RSA キーに基づいて、単一の証明書に基づく認証に明確に制限できます。 これにより、RSA キーが変更された場合に既存のクライアントでサービスが使用できなくなるのと引き換えに、特定の RSA キーをより厳しく認証できます。
ユーザー プリンシパル名 (UPN)。 ClientCredentialType が Windows に設定されており、サービス プロセスがシステム アカウントのいずれかで実行されていない場合の既定値です。 この要素は、サービスを実行中の UPN を指定します。 「認証のためのサービスの ID のオーバーライド」の「Kerberos 認証と ID」セクションを参照してください。 この設定では、サービスが特定の Windows ユーザー アカウントで実行されていることを確認します。 このユーザー アカウントは、現在ログオンしているユーザーである場合もあれば、特定のユーザー アカウントで実行されているサービスである場合もあります。

サービスが Active Directory 環境のドメイン アカウントで実行されている場合、この設定では Windows Kerberos セキュリティを利用します。
サービス プリンシパル名 (SPN)。 ClientCredentialType が Windows に設定されており、サービス プロセスがシステム アカウント (LocalService、LocalSystem、または NetworkService) のいずれかで実行されている場合の既定値です。 この要素は、サービスのアカウントに関連付けられている SPN を指定します。 「認証のためのサービスの ID のオーバーライド」の「Kerberos 認証と ID」セクションを参照してください。 これにより、SPN と SPN に関連付けられた特定の Windows アカウントによってサービスが識別されます。

Setspn.exe ツールを使用すると、サービスのユーザー アカウントに対してコンピューター アカウントを関連付けることができます。

サービスがシステム アカウントのいずれか、または SPN 名に関連付けられたドメイン アカウントで実行されており、コンピューターが Active Directory 環境のドメインのメンバーである場合、この設定では Windows Kerberos セキュリティを利用します。

サービスでの ID の指定

クライアント資格情報の種類を選択すると、サービス メタデータで公開される ID の種類が指定されるため、通常、サービスで ID を設定する必要はありません。 サービス ID をオーバーライドまたは指定する方法の詳細については、「認証のためのサービスの ID のオーバーライド」を参照してください。

構成での <identity> 要素の使用

上記の例で示したバインディングのクライアント資格情報の種類を Certificate, に変更すると、次のコードに示すように、生成される WSDL には、Base64 でシリアル化された、ID 値用の X.509 証明書が含まれます。 これは、Windows 以外のすべてのクライアント資格情報の種類の既定値です。

構成で <identity> 要素を使用するか、コードで ID を設定することにより、既定のサービス ID の値を変更するか、ID の種類を変更することができます。 値 contoso.com を使用してドメイン ネーム システム (DNS) ID を設定する構成コードを次に示します。

プログラムによる ID の設定

ID は、WCF によって自動的に決定されるため、サービスで ID を明示的に指定する必要はありません。 ただし、WCF では、必要に応じてエンドポイントの ID を指定できます。 特定の DNS ID を持つ新しいサービス エンドポイントを追加するコードを次に示します。

ServiceEndpoint ep = myServiceHost.AddServiceEndpoint(
                typeof(ICalculator),
                new WSHttpBinding(),
                String.Empty);
EndpointAddress myEndpointAdd = new EndpointAddress(new Uri("http://localhost:8088/calc"),
     EndpointIdentity.CreateDnsIdentity("contoso.com"));
ep.Address = myEndpointAdd;
Dim ep As ServiceEndpoint = myServiceHost.AddServiceEndpoint(GetType(ICalculator), New WSHttpBinding(), String.Empty)
Dim myEndpointAdd As New EndpointAddress(New Uri("http://localhost:8088/calc"), EndpointIdentity.CreateDnsIdentity("contoso.com"))
ep.Address = myEndpointAdd

クライアントでの ID の指定

設計時に、クライアント開発者は通常、 ServiceModel メタデータ ユーティリティ ツール (Svcutil.exe) を使用してクライアント構成を生成します。 生成された構成ファイル (クライアントが使用するもの) には、サービスの ID が含まれます。 たとえば、次のコードは、前の例で示した DNS ID を指定するサービスから生成されたものです。 クライアントのエンドポイント ID 値が、サービスのエンドポイント ID 値と一致していることに注意してください。 この場合、クライアントは、サービスの Windows (Kerberos) 資格情報を受け取るときに、この値が contoso.com であることを要求します。

サービスでクライアント資格情報の種類として Windows ではなく証明書を指定した場合は、証明書の DNS プロパティの値が contoso.com であることが要求されます (DNS プロパティが null の場合は、証明書のサブジェクト名が contoso.com である必要があります)。

ID の特定の値の使用

次のクライアント構成ファイルは、サービスの ID に特定の値を要求する方法を示しています。 次の例では、クライアントは 2 つのエンドポイントと通信できます。 1 つ目のエンドポイントは証明書の拇印で識別され、もう 1 つは証明書の RSA キーで識別されます。 つまり、公開キーと秘密キーのペアだけが含まれた証明書ですが、この証明書は信頼された証明機関によって発行されたものではありません。

実行時の ID 検査

デザイン時には、クライアント開発者はサービスのメタデータで ID を確認します。 実行時には、サービスのエンドポイントを呼び出す前に ID 検査が実行されます。

ID 値は、メタデータで指定された認証の種類 (つまり、サービスで使用される資格情報の種類) に関連付けられています。

認証に X.509 証明書を使用するメッセージ レベルまたはトランスポート レベルの SSL (Secure Sockets Layer) を使用して認証を行うようにチャネルが構成されている場合、次の ID 値が有効になります。

  • DNS。 WCF は、SSL ハンドシェイク中に提示された証明書に、クライアントの DNS ID に指定された値と等価の DNS または CommonName (CN) 属性が含まれているかどうかを確認します。 この検査は、サーバー証明書の有効性の確認とは別に行われます。 WCF は既定で、信頼されたルート証明機関によってサーバー証明書が発行されているかどうかを検証します。

  • 証明書。 SSL ハンドシェイク中には、WCF により、ID に指定された証明書の正確な値がリモート エンドポイントによって確実に提供されます。

  • 証明書参照。 証明書と同じです。

  • RSA。 SSL ハンドシェイク中には、WCF により、ID に指定された正確な RSA キーがリモート エンドポイントによって確実に提供されます。

サービスが認証に Windows 資格情報を使用するメッセージ レベルまたはトランスポート レベル SSL の認証を行い、資格情報をネゴシエートする場合、次の ID 値が有効になります。

  • DNS。 ネゴシエーションでは、DNS 名を確認できるように、サービスの SPN が渡されます。 SPN の形式は host/<dns name> です。

  • SPN。 サービスの明示的な SPN (例 : host/myservice) が返されます。

  • UPN。 サービス アカウントの UPN です。 UPN の形式は username@domain です。 たとえば、サービスがユーザー アカウントで実行されている場合、UPN は username@contoso.com のようになります。

(Identity プロパティを使用して) ID をプログラムによって指定することは任意です。 ID が指定されておらず、クライアント資格情報の種類が Windows の場合、既定値は、先頭に "host/" リテラルが付加されたサービス エンドポイント アドレスのホスト名の部分に値が設定された SPN になります。 ID が指定されておらず、クライアント資格情報の種類が証明書の場合、既定値は Certificate です。 これは、メッセージ レベルとトランスポート レベルの両方のセキュリティに適用されます。

ID とカスタム バインド

サービスの ID は使用するバインディングの種類によって異なるため、カスタム バインディングの作成時には、適切な ID が公開されていることを確認する必要があります。 たとえば、次のコード例では、セキュリティで保護された通信のブートストラップ バインディングの ID と、エンドポイントのバインディングの ID が一致していないため、セキュリティの種類と適合しない ID が公開されます。 セキュリティで保護された通信のバインディングでは DNS ID が設定され、WindowsStreamSecurityBindingElement では UPN ID または SPN ID が設定されます。

CustomBinding binding = new CustomBinding();
// The following binding exposes a DNS identity.
binding.Elements.Add(SecurityBindingElement.
    CreateSecureConversationBindingElement(
    SecurityBindingElement.
    CreateIssuedTokenForSslBindingElement(
    new IssuedSecurityTokenParameters())));

// The following element requires a UPN or SPN identity.
binding.Elements.Add(new WindowsStreamSecurityBindingElement());
binding.Elements.Add(new TcpTransportBindingElement());
Dim binding As New CustomBinding()
' The following binding exposes a DNS identity.
binding.Elements.Add(SecurityBindingElement.CreateSecureConversationBindingElement(SecurityBindingElement.CreateIssuedTokenForSslBindingElement(New IssuedSecurityTokenParameters())))

' The following element requires a UPN or SPN identity.
binding.Elements.Add(New WindowsStreamSecurityBindingElement())
binding.Elements.Add(New TcpTransportBindingElement())

カスタム バインディング用にバインディング要素を正しくスタックする方法の詳細については、「ユーザー定義のバインディングの作成」を参照してください。 SecurityBindingElement でカスタム バインディングを作成する方法の詳細については、「方法: 指定した認証モード用の SecurityBindingElement を作成する」を参照してください。

関連項目