方法: X.509 証明書を使用してサービスをセキュリティで保護する
X.509 証明書を使用してサービスをセキュリティ保護することは、Windows Communication Foundation (WCF) の大半のバインディングで使用される基本的な手法です。 ここでは、X.509 証明書を使用して自己ホスト サービスを構成する手順を示します。
サーバーの認証に使用できる有効な証明書があることが前提条件になります。 この証明書は、信頼された証明機関によってサーバーに対して発行される必要があります。 証明書が無効な場合、サービスの使用を試みるすべてのクライアントがサービスを信頼しなくなるため、接続が作成されません。 証明書の使用に関する詳細については、「証明書の使用」を参照してください。
コードにより証明書を使用してサービスを構成するには
サービス コントラクトを作成し、サービスを実装します。 詳細については、「サービスの設計と実装」を参照してください。
次のコードに示すように、WSHttpBinding クラスのインスタンスを作成し、そのセキュリティ モードを Message に設定します。
// Create a binding and set the security mode to Message. WSHttpBinding b = new WSHttpBinding(SecurityMode.Message);
' Create a binding and set the security mode to Message. Dim b As New WSHttpBinding(SecurityMode.Message)
次のコードに示すように、2 つの Type 変数を作成し、それぞれコントラクト型と実装されたコントラクトに割り当てます。
Type contractType = typeof(ICalculator); Type implementedContract = typeof(Calculator);
Dim contractType = GetType(ICalculator) Dim implementedContract = GetType(Calculator)
サービスのベース アドレス用に Uri クラスのインスタンスを作成します。
WSHttpBinding
では HTTP トランスポートを使用するため、URI (Uniform Resource Identifier) がこのスキーマで開始されている必要があります。そうでない場合、Windows Communication Foundation (WCF) は、サービスが開かれたときに例外をスローします。Uri baseAddress = new Uri("http://localhost:8044/base");
Dim baseAddress As New Uri("http://localhost:8044/base")
実装したコントラクト型変数と URI を使用して ServiceHost クラスの新しいインスタンスを作成します。
ServiceHost sh = new ServiceHost(implementedContract, baseAddress);
Dim sh As New ServiceHost(implementedContract, baseAddress)
ServiceEndpoint メソッドを使用して、サービスに AddServiceEndpoint を追加します。 次のコードに示すように、コントラクト、バインディング、およびエンドポイント アドレスをコンストラクターに渡します。
sh.AddServiceEndpoint(contractType, b, "Calculator");
sh.AddServiceEndpoint(contractType, b, "Calculator")
任意。 サービスからメタデータを取得するには、新しい ServiceMetadataBehavior オブジェクトを作成し、HttpGetEnabled プロパティを
true
に設定します。ServiceMetadataBehavior sm = new ServiceMetadataBehavior(); sm.HttpGetEnabled = true; sh.Description.Behaviors.Add(sm);
Dim sm As New ServiceMetadataBehavior() sm.HttpGetEnabled = True With sh .Description.Behaviors.Add(sm)
SetCertificate クラスの X509CertificateRecipientServiceCredential メソッドを使用して、有効な証明書をサービスに追加します。 このメソッドでは、いくつかある方法の 1 つを使用して証明書を見つけます。 この例では、FindBySubjectName 列挙体を使用します。 この列挙体では、提供された値が証明書の発行先のエンティティの名前であることを指定します。
sh.Credentials.ServiceCertificate.SetCertificate( StoreLocation.LocalMachine ,StoreName.My, X509FindType.FindBySubjectName ,"localhost");
.Credentials.ServiceCertificate.SetCertificate(StoreLocation.LocalMachine, _ StoreName.My, _ X509FindType.FindBySubjectName, _ "localhost")
Open メソッドを呼び出して、サービスのリッスンを開始します。 コンソール アプリケーションを作成する場合は、ReadLine メソッドを呼び出して、サービスをリッスン状態に保持します。
sh.Open(); Console.WriteLine("Listening"); Console.ReadLine();
.Open() Console.WriteLine("Listening") Console.ReadLine()
例
次の例では、SetCertificate メソッドを使用して、X.509 証明書でサービスを構成します。
// Create a binding and set the security mode to Message.
WSHttpBinding b = new WSHttpBinding(SecurityMode.Message);
Type contractType = typeof(ICalculator);
Type implementedContract = typeof(Calculator);
Uri baseAddress = new Uri("http://localhost:8044/base");
ServiceHost sh = new ServiceHost(implementedContract, baseAddress);
sh.AddServiceEndpoint(contractType, b, "Calculator");
ServiceMetadataBehavior sm = new ServiceMetadataBehavior();
sm.HttpGetEnabled = true;
sh.Description.Behaviors.Add(sm);
sh.Credentials.ServiceCertificate.SetCertificate(
StoreLocation.LocalMachine ,StoreName.My,
X509FindType.FindBySubjectName ,"localhost");
sh.Open();
Console.WriteLine("Listening");
Console.ReadLine();
sh.Close();
' Create a binding and set the security mode to Message.
Dim b As New WSHttpBinding(SecurityMode.Message)
Dim contractType = GetType(ICalculator)
Dim implementedContract = GetType(Calculator)
Dim baseAddress As New Uri("http://localhost:8044/base")
Dim sh As New ServiceHost(implementedContract, baseAddress)
sh.AddServiceEndpoint(contractType, b, "Calculator")
Dim sm As New ServiceMetadataBehavior()
sm.HttpGetEnabled = True
With sh
.Description.Behaviors.Add(sm)
.Credentials.ServiceCertificate.SetCertificate(StoreLocation.LocalMachine, _
StoreName.My, _
X509FindType.FindBySubjectName, _
"localhost")
.Open()
Console.WriteLine("Listening")
Console.ReadLine()
.Close()
End With
コードのコンパイル
コードのコンパイルには次の名前空間が必要です。