2010-02-16 11 views
4

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> 

Répondre

2

Il ne semble pas y avoir un moyen de faire ce que je veux en utilisant web.config.

je fini par ajouter un comportement avec ce tag:

<clientCertificate> 
    <authentication certificateValidationMode="PeerTrust" trustedStoreLocation="CurrentUser" revocationMode="NoCheck"/> 
</clientCertificate> 

Et puis ajoutez le certificat du client au magasin de certificats « personnes de confiance » de l'utilisateur que le serveur exécute.

1

Vérifiez la page WCF Security Guidance sur CodePlex - excellent et des trucs très utiles!

En particulier, consultez le plus How-To et plus précisément la

How To – Use Certificate Authentication and Message Security in WCF calling from Windows Forms

Il explique en détail comment mettre en place un service WCF qui demande à ses clients de présenter un certificat valide et comment vérifier cela. Si vous ne souhaitez autoriser qu'un seul client, déployez ce certificat uniquement pour ce client unique.

Espérons que cela aide!

+0

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. –

+0

@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. –

+0

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. –