J'ai une application client/service WCF qui repose sur une communication sécurisée entre deux machines et je souhaite utiliser des certificats x509 installés dans le magasin de certificats pour: identifier le serveur et le client les uns aux autres. Je fais cela en configurant la liaison comme <security authenticationMode="MutualCertificate"/>
. Il n'y a que la machine client.Comment configurer un service WCF pour n'accepter qu'un seul client identifié par un certificat x509
Le serveur a un certificat émis à server.mydomain.com installé dans le Local Computer/Personal Store et le client a un certificat émis à client.mydomain.com installé au même endroit. En plus de cela, le serveur a le certificat public du client dans Local Computer/Trusted People et le client a le certificat public du serveur dans Local Computer/Trusted People.
Enfin, le client a été configuré pour vérifier le certificat du serveur. Je l'ai fait en utilisant l'élément system.servicemodel/behaviors/endpointBehaviors/clientCredentials/serviceCertificate/defaultCertificate
dans le fichier de configuration.
Jusqu'ici tout va bien, tout cela fonctionne. Mon problème est que je veux spécifier dans le fichier de configuration du serveur que seuls les clients qui s'identifient avec le certificat client.mydomain.com du magasin de certificats Trusted People sont autorisés à se connecter.
Les informations correctes sont disponibles sur le serveur en utilisant le ServiceSecurityContext
, mais je cherche un moyen de spécifier dans app.config que WCF devrait faire cette vérification au lieu de devoir vérifier le contexte de sécurité à partir du code.
Est-ce possible? Tous les indices seraient appréciés.
Soit dit en passant, mon fichier de configuration du serveur ressemble à ceci jusqu'à présent:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service name="MyServer.Server" behaviorConfiguration="CertificateBehavior">
<endpoint contract="Contracts.IMyService" binding="customBinding" bindingConfiguration="SecureConfig">
</endpoint>
<host>
<baseAddresses>
<add baseAddress="http://localhost/SecureWcf"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="CertificateBehavior">
<serviceCredentials>
<serviceCertificate storeLocation="LocalMachine" x509FindType="FindBySubjectName" findValue="server.mydomain.com"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<customBinding>
<binding name="SecureConfig">
<security authenticationMode="MutualCertificate"/>
<httpTransport/>
</binding>
</customBinding>
</bindings>
</system.serviceModel>
</configuration>
C'est un bon exemple, mais il vérifie seulement que le client a un certificat valide - tout certificat valide. N'est-ce pas? Si un client indésirable a la partie publique du certificat racine afin qu'il puisse vérifier le certificat du serveur et que le client indésirable possède également son propre certificat émis par VeriSign, alors il peut se connecter, n'est-ce pas? C'est exactement ce que je veux arrêter. –
@Johan: dépend de ce que vous vérifiez dans votre certificat. Je suis sûr que vous pouvez ajouter une sorte de numéro de série ou quelque chose, et tant que cette clé n'est pas présente (si quelqu'un réussit à voler les parties publiques du certificat), vous ne l'accepterez pas. –
Le certificat possède à la fois un nom distinctif, un numéro de série et une empreinte numérique. Je sais comment vérifier tous les trois dans le code. Je cherchais un moyen de le faire de façon déclarative à partir de app.config au lieu d'impérativement à partir du code. Mais je pense que l'authentification et l'autorisation ont été mélangées lorsque j'ai posé cette question. Une meilleure approche peut consister à authentifier tous les certificats approuvés, puis ajouter une sorte d'autorisation en plus de cela. Peut-être que je dois brancher un code personnalisé pour, par exemple, Mapper une certification à un rôle en quelque sorte, puis se fonder sur l'autorisation basée sur le rôle. –