J'essaie de créer un service WCF4 hébergé sur IIS qui utilisera des certificats X.509 pour la sécurité des messages et SSL avec l'authentification mutuelle requise pour la sécurité du transport (projet spécification nécessite l'utilisation de WS-Security et SSL, AFAIK seul est généralement le chemin à parcourir, mais peu importe).WCF 4 - TransportWithMessageCredential utilisant des certificats X.509 pour le transport et la sécurité des messages
J'ai effectué mon TestRootCA et l'ai utilisé pour délivrer un certificat de serveur (localhost) et un certificat client (TestUser). Je voulais d'abord établir et tester la sécurité du transport uniquement, donc j'ai configuré IIS pour utiliser https, certificat SSL configuré (cert localhost que j'ai fait), et configuré IIS à besoin un certificat client des clients. J'ai ensuite modifié le service web.config, créé le fichier svcutil.conf correspondant et lancé svcutil qui a réussi à créer la classe proxy client et app.config pour mon application WinForms de test. J'ai mis le certificat lors de la création du client proxy en appelant:
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));
Jusqu'ici tout va bien. Mais lorsque je modifie web.config du service pour utiliser TrasportWithMessageCredential (au lieu de Transport) et que je spécifie "Certificate" comme clientCredentialType pour la sécurité des messages, j'obtiens HTTP 403 - The HTTP request was forbidden with client authentication scheme 'Anonymous'
, même si j'ai spécifié "Certificate".
Mon web.config finale ressemble à ceci:
<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>
et mon app.conf client:
<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>
Toutes les idées?
EDIT:
J'ai réussi à le faire fonctionner en changeant les paramètres SSL IIS pour le certificat client de exigent-acceptent. Il semble que lorsque j'introduis la sécurité des messages en utilisant des certificats sur la sécurité de transport en utilisant SSL, le client utilise le certificat pour la signature du message mais pas l'authentification pour l'authentification mutuelle sur SSL (il essaie de se connecter comme anonyme même s'il a un certificat assigné).
Je ne sais pas pourquoi cela se produit, j'aimerais un commentaire d'un expert :).
N'ont pas essayé ceci, mais même si cela fonctionnerait, la nécessité de spécifier un * certificat * client * dans la * configuration * de serveur est un briseur d'affaire. Le serveur ne connaît pas le certificat client à l'avance (et il y a beaucoup de clients différents), il utilise la confiance de la chaîne (si le isssuer du client cert est valide, le cert client est accepté et utilisé comme identification). –
Cela a corrigé l'erreur que je recevais "La requête HTTP était interdite avec le schéma d'authentification client 'Anonymous'". J'ai seulement eu les certificats de serveur spécifiés. Merci – Nanook