IIS でホストされる WCF4 サービスを作成しようとしています。これは、メッセージ セキュリティに X.509 証明書を使用し、トランスポート セキュリティに相互認証が必要な SSL を使用します (プロジェクトの仕様では、WS-Security と SSL の使用が必要です。通常、1 つだけが行きますが、気にしないでください)。
TestRootCA を作成し、それを使用してサーバー証明書 (localhost) とクライアント証明書 (TestUser) を発行しました。最初はトランスポート セキュリティのみを確立してテストしたかったので、https を使用するように IIS を構成し、SSL 証明書 (私が作成したローカルホスト証明書) を構成し、クライアントからのクライアント証明書を要求するように IIS を構成しました。次に、サービス web.config を変更し、対応する svcutil.conf を作成して svcutil を実行すると、テスト用の WinForms アプリのクライアント プロキシ クラスと app.config が正常に作成されました。プロキシ クライアントを作成するときに、次のように呼び出して証明書を設定します。
var client = new ServiceClient();
client.ClientCredentials.ClientCertificate.SetCertificate(System.Security.Cryptography.X509Certificates.StoreLocation.CurrentUser, System.Security.Cryptography.X509Certificates.StoreName.My, System.Security.Cryptography.X509Certificates.X509FindType.FindBySubjectDistinguishedName, "CN=TestUser");
MessageBox.Show(client.GetData(42));
ここまでは順調ですね。しかし、サービスの web.config を (Transport の代わりに) TrasportWithMessageCredential を使用するように変更し、メッセージ セキュリティの clientCredentialType として "Certificate" を指定すると、"Certificate"HTTP 403 - The HTTP request was forbidden with client authentication scheme 'Anonymous'
を指定したにもかかわらず、.
私の最終的な web.config は次のようになります。
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="wsHttpEndpointBinding">
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="Certificate"/>
<message clientCredentialType="Certificate"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="serviceBehavior" name="Service">
<endpoint binding="wsHttpBinding" bindingConfiguration="wsHttpEndpointBinding" name="wsHttpEndpoint" contract="IService" />
<endpoint address="mex" binding="wsHttpBinding" bindingConfiguration="wsHttpEndpointBinding" name="mexEndpoint" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="serviceBehavior">
<serviceMetadata httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
そして私のクライアント app.conf:
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="wsHttpEndpoint" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" />
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="Certificate"/>
<message clientCredentialType="Certificate"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="https://localhost/WCFTestService/Service.svc" binding="wsHttpBinding" bindingConfiguration="wsHttpEndpoint" contract="IService" name="wsHttpEndpoint" />
</client>
</system.serviceModel>
何か案は?
編集:
クライアント証明書の IIS SSL 設定をrequireからacceptに変更することで、なんとか機能させることができました。SSL を使用したトランスポート セキュリティよりも証明書を使用したメッセージ セキュリティを導入すると、クライアントはメッセージの署名に証明書を使用しますが、SSL を介した相互認証には使用しないようです (証明書が割り当てられているにもかかわらず、匿名としてログオンしようとします)。
なぜこれが起こっているのかわからないので、専門家からのコメントが欲しいです:)。