サービス ID と認証
サービスのエンドポイント ID は、サービスの Web サービス記述言語 (WSDL) から生成される値です。この値は、すべてのクライアントに反映され、サービスの認証に使用されます。クライアントがエンドポイントとの通信を開始し、サービスがクライアントに対して認証を行った後に、クライアントは、エンドポイント ID 値とエンドポイントの認証プロセスから返された実際の値を比較します。この 2 つの値が一致した場合、クライアントは要求したサービス エンドポイントに接続していることを確認できます。これは、クライアントが悪質なサービスでホストされたエンドポイントにリダイレクトされるのを防ぎ、フィッシングから保護する役割を果たします。
ID の設定を示すサンプル アプリケーションについては、「サービス ID サンプル」を参照してください。エンドポイントとエンドポイント アドレス詳細情報、「エンドポイントのアドレス」を参照してください。
![]() |
---|
認証に NTLM (NT LanMan) を使用する場合、NTLM ではクライアントがサーバーを認証できないため、サービス ID はチェックされません。NTLM はコンピューターが Windows ワークグループの一部である場合、または Kerberos 認証をサポートしていない古いバージョンの Windows が実行されている場合に使用されます。 |
サービスに対してメッセージを送信するためにクライアントがセキュリティで保護されたチャネルを開始すると、Windows Communication Foundation (WCF) インフラストラクチャはこのサービスを認証し、サービス ID がクライアントの使用するエンドポイント アドレスに指定された ID と一致する場合にのみメッセージを送信します。
ID の処理は、次の 2 段階から成ります。
デザイン時に、クライアント開発者は、(WSDL を通じて公開される) エンドポイントのメタデータでサービスの ID を確認します。
実行時に、クライアント アプリケーションは、メッセージをサービスに送信する前に、サービスのセキュリティ資格情報のクレームを確認します。
クライアントでの ID の処理は、サービスでのクライアント認証と似ています。セキュリティで保護されたサービスは、クライアントの資格情報が認証されるまでコードを実行しません。同様に、クライアントは、サービスのメタデータによって事前に認識されている内容に基づいて、サービスの資格情報が認証されるまでメッセージを送信しません。
EndpointAddress クラスの Identity プロパティは、クライアントによって呼び出されるサービスの ID を表します。サービスはこの Identity をサービスのメタデータ内に公開します。クライアント開発者がサービス エンドポイントに対してServiceModel メタデータ ユーティリティ ツール (Svcutil.exe) を実行すると、生成された構成にはサービスの Identity プロパティの値が含まれます。(セキュリティが構成されている場合) WCF インフラストラクチャは、サービスが指定された ID を所有しているかどうかを検査します。
![]() |
---|
メタデータには、サービスに要求される ID が含まれています。したがって、安全な方法 (サービスの HTTPS エンドポイントを作成するなど) でサービス メタデータを公開することをお勧めします。詳細については、次のトピックを参照してください。、「How to: Secure Metadata Endpoints」を参照してください。 |
ID の種類
サービスが提供できる ID は 5 種類あります。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 xmlns="https://schemas.xmlsoap.org/ws/2006/02/addressingidentity">
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<X509Data>
<X509Certificate>MIIBxjCCAXSgAwIBAgIQmXJgyu9tro1M98GifjtuoDAJBgUrDgMCHQUAMBYxFDASBgNVBAMTC1Jvb3QgQWdlbmN5MB4XDTA2MDUxNzIxNDQyNVoXDTM5MTIzMTIzNTk1OVowKTEQMA4GA1UEChMHQ29udG9zbzEVMBMGA1UEAxMMaWRlbnRpdHkuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDBmivcb8hYbh11hqVoDuB7zmJ2y230f/b4e+4P6yXtKKuhUdYcIqc8mAforIM4WWJEVGeJVq9sFEwqrL5Ryid8jMTRwPLvA/x/wvj1gtD1GWJ+aUh2pqieiGL7MWTepHAQBIibUxgOrAOz0j9Xhg0iDFYScdYUjeqI3yZIDC7WbwIDAQABo0swSTBHBgNVHQEEQDA+gBAS5AktBh0dTwCNYSHcFmRjoRgwFjEUMBIGA1UEAxMLUm9vdCBBZ2VuY3mCEAY3bACqAGSKEc+41KpcNfQwCQYFKw4DAh0FAANBADB/J2QjdSPL8Doj3pAveCXd/5fY03eo9kUym/Tmb4ubdqsObri0qnYR/n8Wxsa1yJ4Dks6cNBTPS4l5B7zUeNo=</X509Certificate>
</X509Data>
</KeyInfo>
</Identity>
構成で <identity> 要素を使用するか、コードで ID を設定することにより、既定のサービス ID の値を変更することも、ID の種類を変更することもできます。値 contoso.com
を使用してドメイン ネーム システム (DNS) ID を設定する構成コードを次に示します。
プログラムによる ID の設定
ID は、WCF によって自動的に決定されるため、サービスで ID を明示的に指定する必要はありません。ただし、WCF では、必要に応じてエンドポイントの ID を指定できます。特定の DNS ID を持つ新しいサービス エンドポイントを追加するコードを次に示します。
Dim ep As ServiceEndpoint = myServiceHost.AddServiceEndpoint(GetType(ICalculator), New WSHttpBinding(), String.Empty)
Dim myEndpointAdd As New EndpointAddress(New Uri("https://localhost:8088/calc"), EndpointIdentity.CreateDnsIdentity("contoso.com"))
ep.Address = myEndpointAdd
ServiceEndpoint ep = myServiceHost.AddServiceEndpoint(
typeof(ICalculator),
new WSHttpBinding(),
String.Empty);
EndpointAddress myEndpointAdd = new EndpointAddress(new Uri("https://localhost:8088/calc"),
EndpointIdentity.CreateDnsIdentity("contoso.com"));
ep.Address = myEndpointAdd;
クライアントでの ID の指定
デザイン時には、クライアント開発者は通常 ServiceModel メタデータ ユーティリティ ツール (Svcutil.exe) を使用してクライアント構成を生成します。生成された構成ファイル (クライアントが使用するもの) には、サービスの ID が含まれます。たとえば、次のコードは、前の例で示した DNS ID を指定するサービスから生成されたものです。クライアントのエンドポイント ID 値が、サービスのエンドポイント ID 値と一致していることに注意してください。この場合、クライアントは、サービスの Windows (Kerberos) 資格情報を受け取るときに、この値が contoso.com
であることを要求します。
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_ICalculator_Windows">
<security>
<message clientCredentialType="Windows"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="https://localhost:8003/servicemodelsamples/service/dnsidentity"
binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_ICalculator_Windows"
contract="ICalculator"
name="WSHttpBinding_ICalculator">
<identity>
<dns value="contoso.com" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
サービスでクライアント資格情報の種類として Windows ではなく証明書を指定した場合は、証明書の DNS プロパティの値が contoso.com
であることが要求されます (DNS プロパティが null の場合は、証明書のサブジェクト名が contoso.com
である必要があります)。
ID の特定の値の使用
次のクライアント構成ファイルは、サービスの ID に特定の値を要求する方法を示しています。次の例では、クライアントは 2 つのエンドポイントと通信できます。1 つ目のエンドポイントは証明書の拇印で識別され、もう 1 つは証明書の RSA キーで識別されます。つまり、公開キーと秘密キーのペアだけが含まれた証明書ですが、この証明書は信頼された証明機関によって発行されたものではありません。
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_ICalculator_Anonymous">
<security>
<message clientCredentialType="None" />
</security>
</binding >
</wsHttpBinding>
</bindings>
<client>
<endpoint
address="https://localhost:8003/servicemodelsamples/service/certificateidentity"
binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_ICalculator_Anonymous"
contract="ICalculator"
name="WSHttpBinding_ICalculator1">
<identity>
<certificate encodedValue="AwAAAAEAAAAUAAAARwEDOI5fk5i0+TbylJ9k8Kljle8gAAAAAQAAAMoBAAAwggHGMIIBdKADAgECAhCZcmDK722ujUz3waJ+O26gMAkGBSsOAwIdBQAwFjEUMBIGA1UEAxMLUm9vdCBBZ2VuY3kwHhcNMDYwNTE3MjE0NDI1WhcNMzkxMjMxMjM1OTU5WjApMRAwDgYDVQQKEwdDb250b3NvMRUwEwYDVQQDEwxpZGVudGl0eS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMGaK9xvyFhuHXWGpWgO4HvOYnbLbfR/9vh77g/rJe0oq6FR1hwipzyYB+isgzhZYkRUZ4lWr2wUTCqsvlHKJ3yMxNHA8u8D/H/C+PWC0PUZYn5pSHamqJ6IYvsxZN6kcBAEiJtTGA6sA7PSP1eGDSIMVhJx1hSN6ojfJkgMLtZvAgMBAAGjSzBJMEcGA1UdAQRAMD6AEBLkCS0GHR1PAI1hIdwWZGOhGDAWMRQwEgYDVQQDEwtSb290IEFnZW5jeYIQBjdsAKoAZIoRz7jUqlw19DAJBgUrDgMCHQUAA0EAMH8nZCN1I8vwOiPekC94Jd3/l9jTd6j2RTKb9OZvi5t2qw5uuLSqdhH+fxbGxrXIngOSzpw0FM9LiXkHvNR42g==" />
</identity>
</endpoint>
<endpoint address="https://localhost:8003/servicemodelsamples/service/rsaidentity"
binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_ICalculator_Anonymous"
contract="ICalculator"
name="WSHttpBinding_ICalculator2">
<identity>
<rsa value="<RSAKeyValue><Modulus>wZor3G/IWG4ddYalaA7ge85idstt9H/2+HvuD+sl7SiroVHWHCKnPJgH6KyDOFliRFRniVavbBRMKqy+UconfIzE0cDy7wP8f8L49YLQ9RlifmlIdqaonohi+zFk3qRwEASIm1MYDqwDs9I/V4YNIgxWEnHWFI3qiN8mSAwu1m8=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
実行時の 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 が設定されます。
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())
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());
カスタム バインディングでバインド要素を正しくスタックする方法詳細情報、「ユーザー定義バインディングの作成」を参照してください。SecurityBindingElement を使用してカスタム バインディングを作成する方法詳細情報、「方法 : 指定した認証モード用の SecurityBindingElement を作成する」を参照してください。
参照
処理手順
方法 : 指定した認証モード用の SecurityBindingElement を作成する
方法 : カスタム クライアント ID 検証機能を作成する
方法 : 証明書のサムプリントを取得する
概念
方法 : SecurityBindingElement を使用してカスタム バインディングを作成する
資格情報の種類の選択
証明書の使用
ServiceModel メタデータ ユーティリティ ツール (Svcutil.exe)
ユーザー定義バインディングの作成