Introduction▲
Les webservices permettent à une application d'appeler à distance une méthode exposée sur un serveur. Les informations échangées transitent par le protocole HTTP et sont formatées en données XML selon la norme SOAP. Ainsi, il est possible de faire communiquer ensemble des applications développées avec des technologies différentes.
Un inconvénient majeur des webservices aujourd'hui est l'absence de vraie sécurité dans les normes officielles. Les sociétés se mettent alors à proposer leurs propres solutions pour pallier ce manque. Cependant, ces initiatives restent souvent propriétaires et font disparaître l'intérêt principal des webservices : la compatibilité universelle du moment qu'une technologie sait lire et écrire du xml et utiliser les sockets.
Cet article a pour but de proposer une solution pour sécuriser les webservices en faisant transiter les données par le protocole HTTPS. L'ajout de couche SSL sur HTTP est supporté par la majorité des serveurs web modernes comme IIS ou Apache par exemple.
Nous utiliserons IIS comme serveur web et implémenterons un webservice en ASP.NET qui sera ensuite consommé dans une Winform cliente.
La configuration utilisée pour ce tutoriel est :
- Windows XP Pro SP1;
- IIS 5.1 avec support de ASP.NET;
- Visual Studio .NET 2003.
Pour avoir des compléments sur l'utilisation des webservices en .NET :
- https://morpheus.developpez.com/WebServicesCSharp/
- https://stephaneey.developpez.com/tutoriel/dotnet/webservice/
Un autre article concernant la mise en place du SSL sous IIS 5.0 dans un domaine Windows 2000 :
- https://webman.developpez.com/articles/windows/ssl/
I. Partie serveur▲
I-A. Création du WebService▲
Veillez à ce que IIS soit démarré en local sur votre machine.
Ouvrez Visual Studio .NET.
Faites « Fichier > Nouveau > Projet » et choisissez « Projets Visual C# > Service web ASP.NET ».
Indiquez dans Emplacement : « http://localhost/WebServicesHTTPS » puis « OK ».
Une nouvelle Solution contenant un nouveau Projet est créée.
Un fichier « Service1.asmx » apparaît aussi, il contiendra la définition de notre Webservice.
Faites un clic droit sur Service1.asmx puis « Afficher le code ».
À cet instant, vous devriez avoir votre projet qui ressemble à ça :
Nous allons maintenant écrire une WebMethod qui va prendre en paramètre deux entiers, les additionner et retourner le résultat.
Remplacez dans le code de Service1.asmx :
// [WebMethod]
// public string HelloWorld()
// {
// return "Hello World";
// }
Par :
[WebMethod]
public
int
AddInteger
(
int
a,
int
b)
{
return
a+
b;
}
La mention [WebMethod] permet d'indiquer que AddInteger doit être accessible à distance.
Appuyez sur « F5 », le webservice se compile et la fenêtre de votre navigateur par défaut se lance.
Vous pouvez alors tester votre webservice en cliquant sur « AddInteger ».
Nous allons maintenant sécuriser ce webservice. Dans un premier temps, un certificat va être créé puis intégré dans IIS et associé à notre répertoire virtuel. « http://localhost/WebServicesHTTPS ».
I-B. Création du certificat▲
Nous allons maintenant créer un certificat qui sera stocké du côté du serveur uniquement et permettra d'autoriser la communication via HTTPS lors de la connexion d'un client.
Rendez-vous sur : http://www.slproweb.com/products/Win32OpenSSL.html.
Téléchargez et installez : « Win32OpenSSL-v0.9.7e.exe » (fichier le plus récent au moment d'écrire cet article). On admettra que l'installation s'est déroulée dans « C:\OpenSSL ».
Lancez une fenêtre DOS et placez-vous dans le répertoire « C:\OpenSSL\bin ».
Tapez la commande : « openssl genrsa -des3 -out TutoHTTPS.key 1024 ».
Indiquez une phrase comme demandé et ne l'oubliez pas.
Une clé privée « TutoHTTPS.key » est créée, ne la divulguez pas… elle est privée.
Tapez la commande suivante dans la fenêtre DOS : « openssl req -new -key TutoHTTPS.key -x509 -days 1095 -out TutoHTTPS.crt ».
Entrez la phrase utilisée dans la génération de TutoHTTPS.key.
Entrez ensuite les quelques informations qui vous sont demandées, mettez un « . » lorsque vous ne souhaitez pas répondre.
Le fichier « TutoHTTPS.crt » créé correspond à l'autorité de certification et est diffusable librement.
Le contenu de votre fenêtre DOS devrait ressembler à ça :
I-C. Configuration de IIS▲
Sous Windows, allez dans « Panneau de configuration > Outils d'administration > Service Internet (IIS) ».
Faites un « clic droit » sur « Site web par défaut » puis « Propriétés ».
Sélectionnez l'onglet « Sécurité du répertoire » puis cliquez sur le bouton « Certificat de serveur… ».
Dans l'assistant, choisissez de « Créer un certificat », donnez-lui comme Nom : « TutoHTTPSIIS ».
Suivez ensuite les instructions, laissez comme fichier de demande : « c:\certreq.txt » et allez jusqu'à cliquer sur « Terminer ».
Nous allons maintenant signer le certificat généré par IIS en utilisant les clés précédemment créées.
Lancez une fenêtre DOS, placez-vous dans « c:\OpenSSL\bin ».
Tapez : « openssl x509 -req -days 365 -in c:\certreq.txt -CA TutoHTTPS.crt -CAkey TutoHTTPS.key -CAcreateserial -out TutoHTTPSIIS.crt ».
Entrez votre phrase secrète.
Le fichier « TutoHTTPSIIS.crt » est maintenant créé dans « c:\OpenSSL\bin ».
La fenêtre DOS correspondant à ces manipulations devrait ressembler à ça :
Note : la chaine « minosis-small » correspond au nom DNS de l'ordinateur sur lequel ce tutoriel a été écrit.
De nouveau, allez dans « Panneau de configuration > Outils d'administration > Service Internet (IIS) ».
Faites un « clic droit » sur « Site web par défaut » puis « Propriétés ».
Sélectionnez l'onglet « Sécurité du répertoire » puis cliquez sur le bouton « Certificat de serveur… »
Choisissez dans l'assistant de « Traiter la demande en attente et installer le certificat ».
Sélectionnez ensuite le nouveau certificat : « C:\OpenSSL\bin\TutoHTTPSIIS.crt ».
Puis continuez l'assistant jusqu'à « Terminer ».
Cliquez sur OK dans la fenêtre de propriétés.
Le certificat de serveur est maintenant installé sur IIS.
Utilisons ce certificat sur le répertoire virtuel du webservice « WebServicesHTTPS ».
Dans « Site web par défaut », faites un clic droit sur le répertoire virtuel « WebServicesHTTPS » puis « Propriétés ».
Sélectionnez l'onglet « Sécurité du répertoire » puis « Communications sécurisées > Modifier… ».
Dans la fenêtre qui apparaît, cochez « Requérir un canal sécurisé » puis « Ok ». « Ok » encore dans la fenêtre de propriétés puis « OK » dans la fenêtre « Héritages outrepassés ».
I-D. Gestion de l'authentification (Facultatif)▲
Cette étape est facultative, elle permet d'associer un utilisateur Windows à la connexion HTTPS au webservice et donc de gérer l'authentification de manière non anonyme (par défaut IIS associe toute connexion à un répertoire virtuel à l'utilisateur ASPNET).
Si cette étape n'est pas suivie, alors la liaison HTTPS servira uniquement à garantir la confidentialité des données.
Dans le code de l'étape 2.3, nous dissocierons les deux cas : avec ou sans authentification.
Dans « Site web par défaut », faites un clic droit sur le répertoire virtuel « WebServicesHTTPS » puis « Propriétés ».
Sélectionnez l'onglet « Sécurité du répertoire » puis « Connexions anonymes et contrôle d'authentification > Modifier… ».
Dans la fenêtre qui apparaît, décochez « Connexion anonyme ».
Créons un utilisateur sous Windows qui sera utilisé pour l'authentification dans notre exemple.
Sous Windows, allez dans « Panneau de configuration > Outils d'administration > Gestion de l'ordinateur ».
Déroulez « Utilisateurs et groupes locaux » puis cliquez sur le répertoire « Utilisateurs ».
Sélectionnez le menu « Action > Nouvel utilisateur… ».
Indiquez les paramètres suivants et cliquez sur « Créer » et fermez la fenêtre de « Gestion de l'ordinateur » :
- Nom d'utilisateur : userHTTPS ;
- Nom complet : userHTTPS ;
- Mot de passe : titi ;
- Confirmer le mot de passe : titi ;
- « L'utilisateur doit changer de mot de passe … » : décoché ;
- « L'utilisateur ne peut pas changer de mot de passe » : coché ;
- « Le mot de passe n'expire jamais » : coché ;
- « Le compte est désactivé » : décoché.
II. Partie cliente▲
II-A. Conception de l'interface, WinForm▲
Ouvrez la solution « WebServicesHTTPS » dans Visual Studio si vous l'aviez fermée.
Faites « Fichier > Nouveau > Projet… » et choisissez « Projets Visual C# > Application Windows ».
Cochez « Ajouter à la solution » et donnez comme nom : « WinCalculService », puis « OK ».
Placez sur la Form, les contrôles comme ci-dessous :
II-B. Ajout du WebService en référence web▲
Référençons le Webservice.
Dans le projet « WinCalculService », faites un clic droit sur « Référence » puis « Ajouter une référence web… ».
Dans la fenêtre qui apparaît, indiquez dans le champ URL : « https://localhost/WebservicesHTTPS/Service1.asmx » puis cliquez sur « Allez à ».
Répondez « Oui » à chaque fenêtre de demande de confirmation.
Lorsque le Webservice est chargé (le lien vers AddInteger doit apparaître dans la zone centrale), indiquez comme « Nom de la référence web » la valeur : « com.minosis.services » (c'est un exemple bien sûr).
Cliquez sur « Ajouter la référence ».
Dans le projet, un dossier « web References » a dû apparaître avec en contenu : « com.minosis.services ».
II-C. Écriture du code▲
Dans la Form1, double-cliquez sur le bouton « button1 », la fenêtre de code s'ouvre.
Ajoutez en haut, les appels aux références suivants :
using
System.
Web.
Services;
using
System.
Web.
Services.
Protocols;
using
System.
Security.
Cryptography.
X509Certificates;
using
System.
Net;
Remplacez ce code :
private
void
button1_Click
(
object
sender,
System.
EventArgs e)
{
}
Par :
1er cas : vous n'avez pas suivi l'étape 1.4, donc pas de gestion de l'authentification, mettez ce code :
private
void
button1_Click
(
object
sender,
System.
EventArgs e)
{
try
{
// On indique la validation automatique des demandes d'acceptation des certificats
System.
Net.
ServicePointManager.
CertificatePolicy =
new
TrustAllCertificatesPolicy
(
);
// Instanciation de la classe proxy permettant l'appel distant au Webservice
com.
minosis.
services.
Service1 serviceAdd =
new
com.
minosis.
services.
Service1
(
);
// Conversion des valeurs String en int
int
a =
Int32.
Parse
(
textBox1.
Text);
int
b =
Int32.
Parse
(
textBox2.
Text);
// Appel à la méthode distante. Son résultat étant un int, on le convertit en String
textBox3.
Text =
serviceAdd.
AddInteger
(
a,
b).
ToString
(
);
}
catch
// Si une exception est levée, on affiche "Erreur" dans la zone de résultat
{
textBox3.
Text =
"Erreur"
;
}
}
// Classe implémentant l'interface System.Net.ICertificatePolicy
// Permet de toujours autoriser l'acceptation des certificats
public
class
TrustAllCertificatesPolicy :
System.
Net.
ICertificatePolicy
{
public
bool
CheckValidationResult
(
ServicePoint sp,
X509Certificate cert,
WebRequest req,
int
problem)
{
return
true
;
}
}
Par :
2e cas : vous avez suivi l'étape 1.4, l'application devra s'identifier avec l'utilisateur « userHTTPS »
private
void
button1_Click
(
object
sender,
System.
EventArgs e)
{
try
{
// On indique la validation automatique des demandes d'acceptation des certificats
System.
Net.
ServicePointManager.
CertificatePolicy =
new
TrustAllCertificatesPolicy
(
);
// Instanciation de la classe proxy permettant l'appel distant au Webservice
com.
minosis.
services.
Service1 serviceAdd =
new
com.
minosis.
services.
Service1
(
);
// Authentification avec l'utilisateur dédié au webservice : userHTTPS
serviceAdd.
Credentials =
new
NetworkCredential
(
"userHTTPS"
,
"titi"
);
// Conversion des valeurs String en int
int
a =
Int32.
Parse
(
textBox1.
Text);
int
b =
Int32.
Parse
(
textBox2.
Text);
// Appel à la méthode distante. Son résultat étant un int, on le convertit en String
textBox3.
Text =
serviceAdd.
AddInteger
(
a,
b).
ToString
(
);
}
catch
// Si une exception est levée, on affiche "Erreur" dans la zone de résultat
{
textBox3.
Text =
"Erreur"
;
}
}
// Classe implémentant l'interface System.Net.ICertificatePolicy
// Permet de toujours autoriser l'acceptation des certificats
public
class
TrustAllCertificatesPolicy :
System.
Net.
ICertificatePolicy
{
public
bool
CheckValidationResult
(
ServicePoint sp,
X509Certificate cert,
WebRequest req,
int
problem)
{
return
true
;
}
}
Vous remarquerez que seule une ligne supplémentaire est nécessaire pour cette authentification :
// Authentification avec l'utilisateur dédié au webservice : userHTTPS
serviceAdd.
Credentials =
new
NetworkCredential
(
"userHTTPS"
,
"titi"
);
Pour tester maintenant :
faites un clic droit sur le projet « WinCalculService » puis « Déboguer > Démarrer une nouvelle instance ».
Si la compilation s'est bien déroulée, la WinForm créée devrait s'afficher et vous pouvez ainsi tester la consommation du webservice « WebServicesHTTPS ».
Tout s'est déroulé en local sur la machine de développement. Évidemment, le but est d'avoir chacun des projets séparés sur des machines distantes.
Téléchargements▲
Téléchargez les sources C# de cet article (la configuration de IIS et du certificat doit être cependant suivie).
Merci à Freegreg pour la relecture.