資格情報ネゴシエーションを使用しない Windows クライアントを使用するメッセージ セキュリティ

次のシナリオは、Kerberos プロトコルによって保護される Windows Communication Foundation (WCF) のクライアントとサービスを示します。

サービスとクライアントは、いずれも同じドメインまたは信頼できるドメインに配置されています。

ms735117.note(ja-jp,VS.100).gif注 :
Windows クライアントとのメッセージ セキュリティ」と異なり、このシナリオでは、アプリケーション メッセージを送信する前にサービスの資格情報をサービスとネゴシエートしません。また、このシナリオでは Kerberos プロトコルを使用するので、Windows ドメイン環境が必要になります。

資格情報ネゴシエーションを使用しないメッセージ セキュリティ

特性 説明

セキュリティ モード

メッセージ

相互運用性

○ Kerberos トークン プロファイル互換クライアントを使用する WS-Security

認証 (サーバー)

サーバーとクライアントの相互認証

認証 (クライアント)

サーバーとクライアントの相互認証

整合性

機密性

トランスポート

HTTP

バインディング

WSHttpBinding

サービス

次のコードと構成は、別々に実行します。以下のいずれかを実行します。

  • 構成を使用せずに、コードを使用してスタンドアロン サービスを作成します。

  • 提供された構成を使用してサービスを作成しますが、エンドポイントを定義しません。

コード

次のコードは、メッセージ セキュリティを使用するサービス エンドポイントを作成します。このコードは、サービス資格情報のネゴシエーションとセキュリティ コンテキスト トークン (SCT) の確立を無効にします。

ms735117.note(ja-jp,VS.100).gif注 :
ネゴシエートせずに Windows の資格情報を使用するには、サービスのユーザー アカウントが、Active Directory ドメインを使用して登録されたサービス プリンシパル名 (SPN) にアクセスする必要があります。これは次の 2 つの方法で実行できます。

  1. NetworkService アカウントまたは LocalSystem アカウントを使用してサービスを実行します。これらのアカウントは、コンピューターが Active Directory ドメインに参加したときに確立されたコンピューターの SPN にアクセスできるため、WCF は適切な SPN 要素をサービスのメタデータ (Web サービス記述言語 (WSDL)) にあるサービスのエンドポイント内部に自動的に生成します。

  2. 任意の Active Directory ドメイン アカウントを使用してサービスを実行します。この場合、そのドメイン アカウント用の SPN を確立する必要があります。これを行うには、Setspn.exe ユーティリティ ツールを使用する方法があります。サービスのアカウント用の SPN を作成したら、SPN をそのメタデータ (WSDL) を通じてサービスのクライアントに公開するように WCF を構成します。これを行うには、アプリケーション構成ファイルまたはコードのどちらかを使用して、公開されるエンドポイントのエンドポイント ID を設定します。プログラムで ID を公開する方法を次の例に示します。

SPN、Kerberos プロトコル、Active Directory 詳細情報、「Kerberos に関する技術的な補足 (Windows 用)」を参照してください。エンドポイント ID 詳細情報、「SecurityBindingElement 認証モード」を参照してください。

' Create the service host.
Dim myServiceHost As New ServiceHost(GetType(ServiceModel.Calculator))

' Create the binding.
Dim binding As New WSHttpBinding()
binding.Security.Mode = SecurityMode.Message
binding.Security.Message.ClientCredentialType = _
   MessageCredentialType.Windows

' Disable credential negotiation and establishment of the
' security context.
binding.Security.Message.NegotiateServiceCredential = False
binding.Security.Message.EstablishSecurityContext = False

' Create a URI for the endpoint address.
Dim httpUri As New Uri("https://localhost/Calculator")

' Create the EndpointAddress with the SPN for the Identity.
Dim ea As New EndpointAddress(httpUri, _
EndpointIdentity.CreateSpnIdentity("service_spn_name"))

' Get the contract from the ICalculator interface (not shown here).
' See the sample applications for an example of the ICalculator.
Dim contract As ContractDescription = ContractDescription.GetContract(GetType(ICalculator))

' Create a new ServiceEndpoint.
Dim se As New ServiceEndpoint(contract, binding, ea)

' Add the service endpoint to the service.
myServiceHost.Description.Endpoints.Add(se)

' Open the service.
myServiceHost.Open()
Console.WriteLine("Listening...")
Console.ReadLine()

' Close the service. 
myServiceHost.Close()
// Create the service host.
ServiceHost myServiceHost = new ServiceHost(typeof(Calculator));

// Create the binding.
WSHttpBinding binding = new WSHttpBinding();
binding.Security.Mode = SecurityMode.Message;
binding.Security.Message.ClientCredentialType =
     MessageCredentialType.Windows;

// Disable credential negotiation and establishment of the
// security context.
binding.Security.Message.NegotiateServiceCredential = false;
binding.Security.Message.EstablishSecurityContext = false;

// Create a URI for the endpoint address.
Uri httpUri = new Uri("https://localhost/Calculator");

// Create the EndpointAddress with the SPN for the Identity.
EndpointAddress ea = new EndpointAddress(httpUri,
    EndpointIdentity.CreateSpnIdentity("service_spn_name"));

// Get the contract from the ICalculator interface (not shown here).
// See the sample applications for an example of the ICalculator.
ContractDescription contract = ContractDescription.GetContract(
    typeof(ICalculator));

// Create a new ServiceEndpoint.
ServiceEndpoint se = new ServiceEndpoint(contract, binding, ea);

// Add the service endpoint to the service.
myServiceHost.Description.Endpoints.Add(se);

// Open the service.
myServiceHost.Open();
Console.WriteLine("Listening...");
Console.ReadLine();

// Close the service. 
myServiceHost.Close();

構成

コードの代わりに次の構成を使用できます。

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.serviceModel>
    <behaviors />
    <services>
      <service behaviorConfiguration="" name="ServiceModel.Calculator">
        <endpoint address="https://localhost/Calculator" 
                  binding="wsHttpBinding"
                  bindingConfiguration="KerberosBinding"
                  name="WSHttpBinding_ICalculator"
                  contract="ServiceModel.ICalculator" 
                  listenUri="net.tcp://localhost/metadata" >
         <identity>
            <servicePrincipalName value="service_spn_name" />
         </identity>
        </endpoint>
      </service>
    </services>
    <bindings>
      <wsHttpBinding>
        <binding name="KerberosBinding">
          <security>
            <message negotiateServiceCredential="false" 
                     establishSecurityContext="false" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <client />
  </system.serviceModel>
</configuration>

クライアント

次のコードと構成は、別々に実行します。以下のいずれかの操作を行います。

  • コード (およびクライアント コード) を使用してスタンドアロン クライアントを作成します。

  • エンドポイント アドレスを定義しないクライアントを作成します。代わりに、引数として構成名を受け取るクライアント コンストラクターを使用します。次に例を示します。

    Dim cc As New CalculatorClient("EndpointConfigurationName")
    
    CalculatorClient cc = new CalculatorClient("EndpointConfigurationName");
    

コード

クライアントを構成する場合のコード例を次に示します。セキュリティ モードは Message に設定され、クライアント資格情報の種類は Windows に設定されています。NegotiateServiceCredential プロパティと EstablishSecurityContext プロパティには、false が設定されていることに注意してください。

ms735117.note(ja-jp,VS.100).gif注 :
ネゴシエートせずに Windows の資格情報を使用するには、サービスとの通信を開始する前に、サービスのアカウントの SPN を使用してクライアントを構成する必要があります。クライアントは SPN を使用して Kerberos トークンを取得し、サービスとの通信を認証し保護します。サービスの SPN を使用してクライアントを構成する方法を次の例に示します。ServiceModel メタデータ ユーティリティ ツール (Svcutil.exe) を使用してクライアントを生成する場合に、サービスのメタデータ (WSDL) にサービスの SPN 情報が含まれていれば、サービスのメタデータからサービスの SPN が自動的にクライアントに伝達されます。サービスのメタデータにサービスの SPN を含めるようにサービスを構成する方法詳細情報、このトピックの「サービス」を参照してください。

SPN、Kerberos、および Active Directory の詳細については、「Kerberos に関する技術的な補足 (Windows 用)」を参照してください。エンドポイント ID 詳細情報、「SecurityBindingElement 認証モード」を参照してください。

' Create the binding.
Dim myBinding As New WSHttpBinding()
myBinding.Security.Mode = SecurityMode.Message
myBinding.Security.Message.ClientCredentialType = _
   MessageCredentialType.Windows

' Disable credential negotiation and the establishment of 
' a security context.
myBinding.Security.Message.NegotiateServiceCredential = False
myBinding.Security.Message.EstablishSecurityContext = False

' Create the endpoint address and set the SPN identity.
' The SPN must match the identity of the service's SPN.
' If using SvcUtil to generate a configuration file, the SPN
' will be published as the <servicePrincipalName> element under the
' <identity> element.
Dim ea As New EndpointAddress(New Uri("http://machineName/calculator"), _
EndpointIdentity.CreateSpnIdentity("service_spn_name"))

' Create the client. 
Dim cc As New CalculatorClient(myBinding, ea)

' Begin using the client.
Try
    cc.Open()

    Console.WriteLine(cc.Add(100, 11))
    Console.ReadLine()

    ' Close the client.
    cc.Close()
Catch tex As TimeoutException
    Console.WriteLine(tex.Message)
    cc.Abort()
Catch cex As CommunicationException
    Console.WriteLine(cex.Message)
    cc.Abort()
Finally
    Console.WriteLine("Closed the client")
    Console.ReadLine()
End Try
// Create the binding.
WSHttpBinding myBinding = new WSHttpBinding();
myBinding.Security.Mode = SecurityMode.Message;
myBinding.Security.Message.ClientCredentialType =
    MessageCredentialType.Windows;

// Disable credential negotiation and the establishment of 
// a security context.
myBinding.Security.Message.NegotiateServiceCredential = false;
myBinding.Security.Message.EstablishSecurityContext = false;

// Create the endpoint address and set the SPN identity.
// The SPN must match the identity of the service's SPN.
// If using SvcUtil to generate a configuration file, the SPN
// will be published as the <servicePrincipalName> element under the
// <identity> element.
EndpointAddress ea = new EndpointAddress(
new Uri("http://machineName/Calculator"),
EndpointIdentity.CreateSpnIdentity("service_spn_name"));

// Create the client. 
CalculatorClient cc =
    new CalculatorClient(myBinding, ea);

// Begin using the client.

try
{
    cc.Open();
    Console.WriteLine(cc.Add(200, 1111));
    Console.ReadLine();

    // Close the client.
    cc.Close();
}

構成

クライアントを構成する場合のコード例を次に示します。<ServicePrincipalName> 要素は、Active Directory ドメイン内でサービスのアカウント用に登録されたサービスの SPN と一致するように設定する必要があります。

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="WSHttpBinding_ICalculator" >
          <security mode="Message">
            <message clientCredentialType="Windows" 
                     negotiateServiceCredential="false"
                     establishSecurityContext="false" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <client>
      <endpoint address="https://localhost/Calculator" 
                binding="wsHttpBinding"
                bindingConfiguration="WSHttpBinding_ICalculator"
                contract="ICalculator"
                name="WSHttpBinding_ICalculator">
        <identity>
          <servicePrincipalName value="service_spn_name" />
        </identity>
      </endpoint>
    </client>
  </system.serviceModel>
</configuration>

参照

概念

セキュリティの概要
サービス ID と認証

その他のリソース

Windows Server AppFabric のセキュリティ モデル