Skip to main content

Sécurité WCF : Authentification par Certificats mutuels

Par Philippe Lothsavan – Microsoft Consulting Service - Microsoft France
Mai 2007 - Cet article est paru dans le magazine Programmez! .

Windows Communication Foundation (WCF), auparavant connu sous le nom de code “Indigo”, est un ensemble de nouvelles technologies de communication Microsoft pour la plate-forme Windows.

Comme dans toutes les architectures orientées services, des questions sur la sécurité telles que l’intégrité, la confidentialité, l’authentification, l’autorisation et l’audit de la communication sont posées. Le modèle de sécurité de WCF apporte une réponse à ces besoins répartie en 3 parties fonctionnelles :

  • Sécurité du transfert : responsable de la confidentialité, de l’intégrité, et de l’authentification.
  • Autorisation : responsable de l’apport d’une infrastructure pour la gestion des autorisations.
  • Audit : responsable de l’enregistrement des événements liés à la sécurité.

Dans cet article, nous nous intéressons essentiellement à la partie « Sécurité du transfert », et plus précisément, à la fonction d’authentification qui peut être réalisée à l’aide de plusieurs types d’identifiants, le plus commun étant le couple « nom d’utilisateur et son mot de passe ».

Avant d’entrer dans le vif du sujet, voici une petite introduction sur les modes de sécurité ainsi que les types d’identités supportés par WCF. Les concepts de base de WCF, tels qu’un «endpoint » regroupant les notions de « contract, bindings, et address » ne seront pas traités dans cet article.

Mode de sécurité et type d’identité

Voici les différents modes de sécurité supportés par WCF :

ModeDescription
Aucun (None)Aucune sécurité.
TransportUtilise un transport sécurisé comme HTTPS pour l’intégrité, la confidentialité et l’authentification mutuelle.
MessageUtilise le standard « WS-Security » pour sécuriser le message SOAP pour l’intégrité, la confidentialité et l’authentification mutuelle.
Mode MixteUtilise un transport sécurisé pour l’intégrité, la confidentialité et l’authentification du serveur. Utilise la sécurité message (WS-Security ou autres standard) pour l’authentification du client.

Nous choisirons le mode « Message » dans notre exemple pour une meilleure interopérabilité grâce au standard « WS-Security ». Une fois ce mode choisi, il nous faut à présent choisir le type d’identité à utiliser. L’objectif de cet article étant de vous guider dans la mise en place d’une authentification par certificats mutuels, nous choisirons évidemment les certificats X.509 comme type d’identité.

Voici les autres types d’identités supportés par le mode de sécurité message :

TypeDescription
Aucun (None)Autorise le service à interagir avec les clients anonymes.
WindowsAutorise l’échange de messages SOAP sous le contexte d’authentification de Windows. (Kerberos ou NTLM)
Nom d’utilisateur(Username)Autorise le service à interagir uniquement avec les clients authentifiés à l’aide d’un nom d’utilisateur comme identité.
Certificat (Certificate)Autorise le service à interagir uniquement avec les clients authentifiés à l’aide d’un certificat.
Windows CardSpaceAutorise le service à interagir uniquement avec les clients authentifiés à l’aide de Windows CardSpace.

Remarque : Il est intéressant de noter au passage que WCF supporte « CardSpace » comme type d’identité avec le mode message, ce qui n’est pas de cas avec le mode transport.

Authentification par certificats mutuels

Nous voici dans le vif du sujet, à savoir quelles sont les étapes à suivre pour la mise en place d’un service et d’un client WCF avec un mode de sécurité « Message » et des certificats mutuels comme identifiants. Pourquoi mutuels me direz-vous? Et bien tout simplement parce que le client et le service sont authentifiés par deux certificats, un pour le client et l’autre pour le service. Ceci permet au client de vérifier de façon sûre et digne de confiance l’identité du service et réciproquement.

Architecture

Voici les caractéristiques du modèle de sécurité que nous allons mettre en œuvre :

CaractéristiqueDescription
Mode de sécuritéMessage
InteropérabilitéOui, avec les clients et services compatibles avec la norme WS-Security et des certificats X.509 token profile.
AuthentificationAuthentification mutuel du service et client.
IntégritéOui
ConfidentialitéOui
Transporthttp
BindingWSHttpBinding

Remarque : Dans notre exemple, la négociation d’identité entre le client et le service sera désactivée. Les certificats doivent donc être installés sur le client et le serveur en amont de toute communication. L’attribut qui contrôle cette négociation est « NegotiateServiceCredential », activé par défaut.

Notre première étape consiste à créer les certificats pour le service et le client WCF. Par la suite, nous définirons les « endpoint » associés.

Etape 1: Création des certificats

Nous utilisons les certificats générés par l’outil « Création de certificats » (Makecert.exe) fourni avec le Kit de développement du Framework .Net dans notre environnent de développement. En production, ces certificats devront être obtenus à l’aide d’une autorité de certification. Il est recommandé de créer les scripts afin d’automatiser cette étape et de pouvoir la rejouer dans cet environnement ou dans un autre tel que l’environnement de validation par exemple.

Création du certificat service (server)

Ce certificat permettra au client de s’assurer de l’identité du service. Pour cela, nous allons utiliser l’outil de création « Makecert » avec les options suivantes :

  • -sr : Spécifie l'emplacement du magasin du certificat du sujet. En général, défini à « LocalMachine » pour un service.
  • -ss : Spécifie le nom du magasin du certificat du sujet qui stocke le certificat de sortie. Cette valeur peut être spécifique à une application ou “My” pour le magasin personnel.
  • -sky : Spécifie le type de clé du sujet, qui doit être signature, exchange ou un entier qui représente un type de fournisseur. Dans notre cas, nous choisissons “exchange” pour que la clé publique puisse être échangée.
  • -pe : Marque la clé privée générée comme étant exportable. Cela permet l'inclusion de la clé privée dans le certificat généré.
  • -a : Spécifie l'algorithme de signature. Doit être md5 (valeur par défaut) ou sha1.
  • -CN : Spécifie le nom du certificat du sujet. La méthode la plus simple consiste à faire précéder le nom de CN= et d'entourer le tout entre guillemets, dans notre cas, nous utilisons le nom de domaine pleinement qualifié (FQDN) du serveur.
  • La dernière option spécifie le nom du fichier .cer dans lequel le certificat de test X.509 sera écrit.

La commande suivante permet de créer un certificat auto signé, avec les options définies précédemment :

makecert -sr LocalMachine -ss My -sky exchange -pe -a sha1 -n CN=ServerFQDN WCFServerCert.cer

Attention: A chaque exécution de cette commande, un certificat va être crée et ajouté au magasin. Sa duplication engendrera un problème lors d’un accès par nom du sujet. Si vous avez besoin d’identifier précisément le certificat à utiliser, utilisez plutôt son « thumb print » qui unique. Mais soyez averti que cette valeur sera modifiée en cas de renouvèlement. Le plus simple reste à supprimer les doublons.

Certificate

Comme notre service WCF est hébergé dans IIS :

  • Le nom présenté par le « CN » du certificat X.509 doit correspondre avec le nom de domaine pleinement qualifié (FQDN) du serveur qui héberge le service WCF.
  • Il faut donner la permission de lecture à ce certificat au compte « SERVICE RESEAU » ou “NETWORK SERVICE” sur un serveur Windows 2003 à l’aide du script ci-dessous :

echo ************
echo Donne le droit de lecture sur le certificat serveur
echo ************
for /F "delims=" %%i in ('"C:\FindPrivateKey.exe" My LocalMachine -n CN^= ServerFQDN -a') do set PRIVATE_KEY_FILE=%%i
echo Y|cacls.exe "%PRIVATE_KEY_FILE%" /E /G "NETWORK SERVICE":R

Création du certificat client (poste client)

Ce certificat permettra au service de s’assurer de l’identité du client. Attention à ne pas confondre ici le processus d’authentification qui est différent du processus d’autorisation. Une fois authentifié avec l’identité du client (son certificat dans notre cas), le service peut alors décider d’autoriser ou non l’accès à ses services.

La commande suivante permet de créer un certificat auto signé, avec les options suivantes :

makecert -sr CurrentUser -ss My -sky exchange -pe -a sha1 -n CN=WebCenter WCFClientCert.cer

Vous avez ici les mêmes options que pour la création du certificat serveur, les seules différences sont :

  • -sr : Pour le client, le magasin de stockage est généralement défini à « CurrentUser ».
  • -CN : Ici, nous utiliserons le nom de l’application « WebCenter ».

Si le certificat n’a pas été crée sur le poste client, ou s’il y a plusieurs postes clients, installer le certificat précédemment crée dans le magasin « Personal » de « Local Computer » à l’aide de ce script.

echo off
echo ************
echo Installe le certificat client sur le poste client
echo ************
certmgr.exe -add WCFClientCert.cer -r CurrentUser -s My

Remarque : Ce script utilise l’outil « Certificate Manager Tool » (Gestionnaire de certificats) aussi fourni avec le kit de développement du Framework .Net.

Attention : L'outil de création de certificats crée des certificats X.509 uniquement à des fins de tests. Ces certificats ne doivent pas être utilisés dans un environnement de production, ils nous permettent juste de valider le fonctionnement dans des environnements de développement, de tests, et de validation. De plus, par défaut, cet outil crée les certificats dont l’autorité racine est appelée « Root Agency ». Cette autorité n’étant pas une autorité de confiance certifiée, ces certificats ne sont pas sûrs. Pour se rapprocher un peu plus de l’environnent de production, il est possible de créer en amont des certificats client et serveur un certificat qui jouera ce rôle d’autorité de confiance.

Pour plus d’informations sur l’utilisation de ces outils de création et de gestion de certificat X.509, rendez-vous sur le site Msdn aux adresses suivantes:

Installation croisée des certificats

Puisque nous n’effectuons pas de négociation d’identité dans notre exemple, le certificat du serveur doit être installé sur le poste client en amont de toute communication et réciproquement.

Le script suivant installe le certificat du serveur sur le poste client dans le magasin « Personal » du « Local Computer ».

echo off
echo ************
echo Installe le certificat du serveur sur le poste client
echo ************
certmgr.exe -add WCFServerCert.cer -r CurrentUser -s My

Le script suivant installe le certificat du client sur le serveur dans le magasin « TrustedPeople » du « Local Computer ».

echo off
echo ************
echo Installe le certificat du client sur le serveur
echo ************
certmgr.exe -add WCFClientCert.cer -r LocalMachine -s TrustedPeople

Remarque : Vous pouvez vérifier la bonne installation des certificats à l’aide de la console « MMC ».

Console MMC

Etape 2: Création du Endpoint service

Une fois ces certificats créés et installés, il nous faut maintenant paramétrer le service pour le faire fonctionner avec le mode de sécurité choisi.

Pour créer un « endpoint », WCF offre deux possibilités :

  • Soit programmatiquement via les APIs.
  • Soit via un fichier de configuration, ce qui à mon avis, est bien plus pratique (pas besoin de compilation en cas de changement).

Pour cela, nous pouvons soit :

  • Utiliser l’outil de paramétrage WCF « WCF Service Configuration Editor… » accessible directement dans le menu « Outil » de Visual Studio 2005 :

WCF Service Configuration Editor

  • Editer directement le fichier de configuration en suivant ces étapes :
    • Ouvrir le fichier de configuration « app.config » ou « web.confg » dans Visual Studio.
    • Créer une section « serviceBehaviors » pour définir un comportement qui utilise notre certificat avec une recherche par nom du sujet (CN) et valide le certificat du client avec le mode « PeerOrChainTrust » :
      <serviceBehaviors>
      <behavior name="WebCenterServiceBehaviorx509">
      <serviceCredentials>
      <clientCertificate>
      <authentication certificateValidationMode="PeerOrChainTrust" />
      </clientCertificate>
      <serviceCertificate
      findValue="ServerFQDN"
      storeLocation= "LocalMachine"
      storeName="My"
      x509FindType="FindBySubjectName" />
      </serviceCredentials>
      </behavior>
      </serviceBehaviors>

      Remarque : Le mode « PeerOrChainTrust » utilisé valide le certificat s’il le trouve dans le magasin « TrustedPeople », il est pratique en développement car il ne vérifie pas l’autorité racine du certificat (CA). En production, il est préférable d’utiliser le mode « ChainTrust ».

    • Ensuite, créer une section « bindings » pour définir un mode de sécurité à « message » et un certificat comme identité d’authentification :
      <bindings>
      <wsHttpBinding>
      <binding name="WebCenterServiceBindingx509">
      <security>
      <message clientCredentialType="Certificate"
      negotiateServiceCredential="false" />
      </security>
      </binding>
      </wsHttpBinding>
      </bindings>
    • Enfin, pour terminer créer un « endpoint » service qui va utiliser le « behavior » et « bindings » précédemment définis :
      <service name="WebCenterService"
      behaviorConfiguration="WebCenterServiceBehaviorx509" >
      <endpoint binding="wsHttpBinding"
      bindingConfiguration=" WebCenterServiceBindingx509"
      contract="WebCenter.Interfaces.IWebCenterService" />
      </service>
    • Vérifier que le service fonctionne correctement sous Internet Explorer avec l’url du service.
      Vérifier que le service fonctionne correctement sous Internet Explorer avec l’url du service

Etape 3: Création du Endpoint client

Une fois le service opérationnel, il nous reste plus qu’à paramétrer le client pour qu’il communique correctement avec le service.

  • Ouvrir le fichier de configuration « app.config » ou « web.confg » dans Visual Studio.
  • Commencer par créer une section « endpointBehaviors » pour définir un comportement qui utilise notre certificat avec une recherche par nom du sujet (CN) et valide le certificat serveur avec le mode « PeerOrChainTrust » :

<endpointBehaviors>
<behavior name="WebCenterClientBehaviorx509">
<clientCredentials>
<clientCertificate findValue="WebCenter" storeLocation= "LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
<serviceCertificate>
<authentication certificateValidationMode="PeerOrChainTrust" />
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>

  • Ensuite, créer une section « bindings » pour définir un mode de sécurité à « message » et un certificat comme identité d’authentification :

<bindings>
<wsHttpBinding>
<binding name="WebCenterClientBindingx509">
<security>
<message clientCredentialType="Certificate" negotiateServiceCredential="false" />
</security>
</binding>
</wsHttpBinding>
</bindings>

  • Enfin, pour terminer créer notre « endpoint » client qui va utiliser le « behavior » et « bindings » précédemment définis :

<client>
<endpoint name="WSHttpBinding_IWebCenterService"
address=http://192.168.150.1/WebCenterV1/SecurityService.svc
binding="wsHttpBinding"
bindingConfiguration="WebCenterClientBindingx509"
behaviorConfiguration="WebCenterClientBehaviorx509"
contract="WebCenter.Interfaces.IWebCenterService" />
</client>

Conclusion

En choisissant les certificats comme identité d’authentification dans cet exemple, l’objectif était de vous montrer sa simplicité de mise en œuvre avec WCF. Aussi, nous avons choisi l’utilisation d’un seul certificat comme identité d’authentification des clients. Mais il est tout à fait possible et même recommandable de créer un certificat unique par client.

En conclusion, WCF offre un choix important dans la sécurisation d’une communication, tant au niveau de son mode de sécurité que du type d’identité supporté. Vous remarquerez aussi que je ne fais aucune référence quand à l’implémentation, puisque avec ce modèle, il est intéressant de constater que la sécurité peut être mise en œuvre après l’implémentation du code métier, et ceci uniquement par le biais de fichiers de configurations.

Microsoft réalise une enquête en ligne pour comprendre votre opinion sur le site Web de. Si vous choisissez de participer, l’enquête en ligne vous sera présentée lorsque vous quitterez le site Web de.

Souhaitez-vous y participer ?