Ich versuche, einen auf IIS gehosteten WCF4-Dienst zu erstellen, der X.509-Zertifikate für die Nachrichtensicherheit und SSL mit der erforderlichen gegenseitigen Authentifizierung für die Transportsicherheit verwendet (die Projektspezifikation erfordert die Verwendung von WS-Security UND SSL, AFAIK nur eine ist normalerweise der Weg zu gehen, aber egal).
Ich habe mein TestRootCA erstellt und damit ein Server-Zertifikat (localhost) und ein Client-Zertifikat (TestUser) ausgestellt. Ich wollte zunächst nur die Transportsicherheit herstellen und testen, also konfigurierte ich IIS für die Verwendung von https, konfigurierte das SSL-Zertifikat (localhost-Zertifikat, das ich erstellt hatte) und konfigurierte IIS für erfordern ein Client-Zertifikat von Kunden. Ich änderte dann Service web.config, machte die entsprechende svcutil.conf und lief svcutil, die erfolgreich Client-Proxy-Klasse und app.config für meine Test-WinForms-Anwendung gemacht. Ich setzte das Zertifikat beim Erstellen von Proxy-Client durch Aufruf:
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));
So weit, so gut. Aber wenn ich die web.config des Dienstes ändere, um TrasportWithMessageCredential (anstelle von Transport) zu verwenden und "Certificate" als clientCredentialType für die Nachrichtensicherheit anzugeben, erhalte ich HTTP 403 - The HTTP request was forbidden with client authentication scheme 'Anonymous'
obwohl ich "Zertifikat" angegeben habe.
Meine endgültige web.config sieht wie folgt aus:
<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>
und meine client 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>
Irgendwelche Ideen?
EDITAR:
Ich habe es geschafft, es zum Laufen zu bringen, indem ich die IIS SSL-Einstellungen für das Client-Zertifikat von erfordern a akzeptieren . Wenn ich Nachrichtensicherheit mit Zertifikaten über Transportsicherheit mit SSL einführe, scheint es, dass der Client das Zertifikat für die Nachrichtensignierung verwendet, aber pas für die gegenseitige Authentifizierung über SSL (es wird versucht, sich als anonyme obwohl sie ein Zertifikat zugewiesen bekommen hat).
Ich bin mir nicht sicher, warum das passiert, ich hätte gerne einen Kommentar von einem Experten :).