次の方法で共有


カスタム セキュリティで保護されたメタデータ エンドポイント

CustomMexEndpoint サンプルでは、メタデータ交換以外のバインディングのいずれかを使用するセキュリティで保護されたメタデータ エンドポイントを使用してサービスを実装する方法と、このようなメタデータ エンドポイントからメタデータをフェッチするように ServiceModel メタデータ ユーティリティ ツール (Svcutil.exe) またはクライアントを構成する方法を示します。 メタデータ エンドポイントを公開するために使用できるシステム提供のバインドには、mexHttpBinding と mexHttpsBinding の 2 つがあります。 mexHttpBinding は、セキュリティで保護されていない方法で HTTP 経由でメタデータ エンドポイントを公開するために使用されます。 mexHttpsBinding は、セキュリティで保護された方法で HTTPS 経由でメタデータ エンドポイントを公開するために使用されます。 このサンプルでは、 WSHttpBindingを使用してセキュリティで保護されたメタデータ エンドポイントを公開する方法を示します。 これは、バインディングのセキュリティ設定を変更するが、HTTPS を使用しない場合に行う必要があります。 mexHttpsBinding を使用する場合、メタデータ エンドポイントはセキュリティで保護されますが、バインド設定を変更する方法はありません。

このサンプルのセットアップ手順とビルド手順は、このトピックの最後にあります。

サービス

このサンプルのサービスには、2 つのエンドポイントがあります。 アプリケーション エンドポイントは、ReliableSessionが有効で、証明書を使用してセキュリティをMessageWSHttpBindingICalculator コントラクトを提供します。 メタデータ エンドポイントでは、同じセキュリティ設定で WSHttpBindingも使用されますが、 ReliableSessionは使用されません。 関連する構成を次に示します。

<services>
    <service name="Microsoft.ServiceModel.Samples.CalculatorService"
             behaviorConfiguration="CalculatorServiceBehavior">
     <!-- use base address provided by host -->
     <endpoint address=""
       binding="wsHttpBinding"
       bindingConfiguration="Binding2"
       contract="Microsoft.ServiceModel.Samples.ICalculator" />
     <endpoint address="mex"
       binding="wsHttpBinding"
       bindingConfiguration="Binding1"
       contract="IMetadataExchange" />
     </service>
 </services>
 <bindings>
   <wsHttpBinding>
     <binding name="Binding1">
       <security mode="Message">
         <message clientCredentialType="Certificate" />
       </security>
     </binding>
     <binding name="Binding2">
       <reliableSession inactivityTimeout="00:01:00" enabled="true" />
       <security mode="Message">
         <message clientCredentialType="Certificate" />
       </security>
     </binding>
   </wsHttpBinding>
 </bindings>

他の多くのサンプルでは、メタデータ エンドポイントは既定の mexHttpBindingを使用しますが、セキュリティで保護されていません。 ここでは、メタデータはMessageセキュリティでWSHttpBindingを使用してセキュリティ保護されます。 メタデータ クライアントがこのメタデータを取得するには、一致するバインディングを使用して構成する必要があります。 このサンプルでは、このような 2 つのクライアントを示します。

最初のクライアントは、Svcutil.exe を使用してメタデータをフェッチし、デザイン時にクライアント コードと構成を生成します。 サービスはメタデータに既定以外のバインドを使用するため、Svcutil.exe ツールは、そのバインドを使用してサービスからメタデータを取得できるように、特別に構成する必要があります。

2 番目のクライアントは、 MetadataResolver を使用して既知のコントラクトのメタデータを動的にフェッチし、動的に生成されたクライアントで操作を呼び出します。

Svcutil クライアント

既定のバインドを使用して IMetadataExchange エンドポイントをホストする場合は、そのエンドポイントのアドレスを使用して Svcutil.exe を実行できます。

svcutil http://localhost/servicemodelsamples/service.svc/mex

それは動作します。 ただし、このサンプルでは、サーバーは既定以外のエンドポイントを使用してメタデータをホストします。 そのため、Svcutil.exe は、適切なバインディングを使用するように指示する必要があります。 これは、Svcutil.exe.config ファイルを使用して行うことができます。

Svcutil.exe.config ファイルは、通常のクライアント構成ファイルのようになります。 唯一の異常な側面は、クライアント エンドポイントの名前とコントラクトです。

<endpoint name="http"
          binding="wsHttpBinding"
          bindingConfiguration="Binding1"
          behaviorConfiguration="ClientCertificateBehavior"
          contract="IMetadataExchange" />

エンドポイント名は、メタデータがホストされているアドレスのスキームの名前であり、エンドポイント コントラクトを IMetadataExchangeする必要があります。 したがって、次のようなコマンド ラインを使用して Svcutil.exe を実行する場合は、次のようになります。

svcutil http://localhost/servicemodelsamples/service.svc/mex

"http" という名前のエンドポイントとコントラクト IMetadataExchange を検索して、メタデータ エンドポイントとの通信交換のバインドと動作を構成します。 サンプルの Svcutil.exe.config ファイルの残りの部分では、メタデータ エンドポイントのサーバーの構成と一致するバインド構成と動作資格情報を指定します。

Svcutil.exe が Svcutil.exe.configで構成を取得するには、Svcutil.exe 構成ファイルと同じディレクトリに存在する必要があります。 その結果、Svcutil.exe をインストール場所から、Svcutil.exe.config ファイルを含むディレクトリにコピーする必要があります。 その後、そのディレクトリから次のコマンドを実行します。

.\svcutil.exe http://localhost/servicemodelsamples/service.svc/mex

先頭の ".\" は、このディレクトリ内の Svcutil.exe のコピー (対応する Svcutil.exe.configを持つもの) が確実に実行されるようにします。

MetadataResolver クライアント

クライアントがコントラクトと、デザイン時にメタデータと通信する方法を認識している場合、クライアントは、 MetadataResolverを使用してアプリケーション エンドポイントのバインドとアドレスを動的に見つけることができます。 このサンプル クライアントでは、MetadataExchangeClientを作成して構成することで、MetadataResolverで使用されるバインドと資格情報を構成する方法を示します。

Svcutil.exe.config に表示されたのと同じバインディングと証明書の情報を、 MetadataExchangeClientで命令的に指定できます。

// Specify the Metadata Exchange binding and its security mode
WSHttpBinding mexBinding = new WSHttpBinding(SecurityMode.Message);
mexBinding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;

// Create a MetadataExchangeClient for retrieving metadata, and set the // certificate details
MetadataExchangeClient mexClient = new MetadataExchangeClient(mexBinding);
mexClient.SoapCredentials.ClientCertificate.SetCertificate(    StoreLocation.CurrentUser, StoreName.My,
    X509FindType.FindBySubjectName, "client.com");
mexClient.SoapCredentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.PeerOrChainTrust;
mexClient.SoapCredentials.ServiceCertificate.SetDefaultCertificate(    StoreLocation.CurrentUser, StoreName.TrustedPeople,
    X509FindType.FindBySubjectName, "localhost");

mexClient構成すると、関心のあるコントラクトを列挙し、MetadataResolverを使用して、それらのコントラクトを使用してエンドポイントの一覧を取得できます。

// The contract we want to fetch metadata for
Collection<ContractDescription> contracts = new Collection<ContractDescription>();
ContractDescription contract = ContractDescription.GetContract(typeof(ICalculator));
contracts.Add(contract);
// Find endpoints for that contract
EndpointAddress mexAddress = new EndpointAddress(ConfigurationManager.AppSettings["mexAddress"]);
ServiceEndpointCollection endpoints = MetadataResolver.Resolve(contracts, mexAddress, mexClient);

最後に、これらのエンドポイントからの情報を使用して、アプリケーション エンドポイントと通信するためのチャネルの作成に使用される ChannelFactory のバインディングとアドレスを初期化できます。

ChannelFactory<ICalculator> cf = new ChannelFactory<ICalculator>(endpoint.Binding, endpoint.Address);

このサンプル クライアントの重要なポイントは、 MetadataResolverを使用していて、メタデータ交換通信にカスタム バインドまたは動作を指定する必要がある場合は、 MetadataExchangeClient を使用してそれらのカスタム設定を指定できることを示することです。

サンプルを設定してビルドするには

  1. Windows Communication Foundation サンプル One-Time セットアップ手順を実行していることを確認します。

  2. ソリューションをビルドするには、「 Windows Communication Foundation サンプルのビルド」の手順に従います。

同じコンピューターでサンプルを実行するには

  1. サンプルのインストール フォルダーから Setup.bat を実行します。 これにより、サンプルの実行に必要なすべての証明書がインストールされます。 Setup.bat では、FindPrivateKey.exe ツールを使用します。このツールは、 Windows Communication Foundation サンプルのOne-Time セットアップ 手順から setupCertTool.bat を実行してインストールされます。

  2. \MetadataResolverClient\bin または \SvcutilClient\bin からクライアント アプリケーションを実行します。 クライアント アクティビティがクライアント コンソール アプリケーションに表示されます。

  3. クライアントとサービスが通信できない場合は、「WCF サンプルのトラブルシューティングのヒント」を参照してください。

  4. サンプルが完了したら、Cleanup.bat を実行して証明書を削除します。 他のセキュリティ サンプルでは、同じ証明書が使用されます。

マシン間でサンプルを実行するには

  1. サーバーで、setup.bat service実行します。 setup.bat引数を指定してserviceを実行すると、マシンの完全修飾ドメイン名を持つサービス証明書が作成され、サービス証明書が Service.cer という名前のファイルにエクスポートされます。

  2. サーバーで、新しい証明書名を反映するように Web.config を編集します。 つまり、<serviceCertificate> 要素のfindValue属性を、マシンの完全修飾ドメイン名に変更します。

  3. Service.cer ファイルをサービス ディレクトリからクライアント コンピューター上のクライアント ディレクトリにコピーします。

  4. クライアントで、setup.bat client実行します。 setup.bat引数を指定してclientを実行すると、Client.com という名前のクライアント証明書が作成され、Client.cerという名前のファイルにクライアント証明書がエクスポートされます。

  5. クライアント コンピューター上の MetadataResolverClient の App.config ファイルで、mex エンドポイントのアドレス値をサービスの新しいアドレスと一致するように変更します。 これを行うには、localhost をサーバーの完全修飾ドメイン名に置き換えます。 また、metadataResolverClient.cs ファイル内の "localhost" の出現箇所を、新しいサービス証明書名 (サーバーの完全修飾ドメイン名) に変更します。 SvcutilClient プロジェクトの App.config に対して同じことを行います。

  6. Client.cer ファイルをクライアント ディレクトリからサーバー上のサービス ディレクトリにコピーします。

  7. クライアントで、ImportServiceCert.bat実行します。 これにより、Service.cer ファイルから CurrentUser - TrustedPeople ストアにサービス証明書がインポートされます。

  8. サーバーで、ImportClientCert.bat実行します。これにより、Client.cer ファイルから LocalMachine - TrustedPeople ストアにクライアント証明書がインポートされます。

  9. サービス マシンで、Visual Studio でサービス プロジェクトをビルドし、Web ブラウザーでヘルプ ページを選択して実行されていることを確認します。

  10. クライアント コンピューターで、VS から MetadataResolverClient または SvcutilClient を実行します。

    1. クライアントとサービスが通信できない場合は、「WCF サンプルのトラブルシューティングのヒント」を参照してください。

サンプルの実行後にクリーンアップするには

  • サンプルの実行が完了したら、samples フォルダーで Cleanup.bat を実行します。

    このスクリプトでは、複数のコンピューターでこのサンプルを実行する場合、クライアント上のサービス証明書は削除されません。 コンピューター間で証明書を使用する Windows Communication Foundation (WCF) サンプルを実行している場合は、CurrentUser - TrustedPeople ストアにインストールされているサービス証明書を必ずクリアしてください。 これを行うには、次のコマンドを使用します: certmgr -del -r CurrentUser -s TrustedPeople -c -n <Fully Qualified Server Machine Name>。 たとえば、 certmgr -del -r CurrentUser -s TrustedPeople -c -n server1.contoso.comと指定します。