ASP.NET 2.0: Implémenter son propre Membership provider en 30 minutes

N'hésitez pas à commenter cet article ! Commentez Donner une note à l'article (5)

Article lu   fois.

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

Article au format pdf

Vous pouvez télécharger l'article au format pdf à l'adresse http://ditch.developpez.com/aspnet2/membershipprovider/pdf/

L'article au format html se trouve à l'adresse http://ditch.developpez.com/aspnet2/membershipprovider/

Historique

Il y a quelques années, nous n'avions que ASP pour réaliser nos applications. Il fallait dès lors écrire toutes les méthodes pour gérer les utilisateurs au travers de l'application.

Ensuite, avec l'arrivée d'asp.net 1.x, cette gestion a été simplifiée grâce à l'arrivée du mode d'autentification "forms". Malheureusement il restait pas mal de code à écrire...

Asp.net 2.0 amène toute une série de nouveautés concernant la gestion des utilisateurs. On y retrouve:

  • des providers (la couche d'accès aux données en quelque sorte)
  • des composants (la partie visuelle du membership)
  • des API

On retrouve aussi les différentes couches nécessaires à l'implémentation d'une gestion d'utilisateurs, ce qui nous permet de nous concentrer sur le coeur de l'application que nous réalisons.

Nous allons dès lors présenter chacune des couches.

Les "API Membership"

A quoi servent les API Membership? Elles permettent de:

  • Créer des utilisateurs
  • Sauvegarder des informations dans des environnements différents
  • Authentifier des utilisateurs
  • Gérer des mots de passe

Quel est l'intérêt d'utiliser ces API? Par définition il s'agit de faire l'interface entre les applications et les sources de données.

De plus, asp.net 2.0 est "prêt" à utiliser ces différentes API. Effectivement, tous les composants "Login", comme LoginName, Login, CreateUser, ... utilisent ces API.

Membership service

Image non disponible

Sur ce schéma, on peut y voir plusieurs couches (de bas en haut):

  • Sources de données
  • Providers
  • APIs
  • Contrôles de login

Sources de données

Il s'agit des bases de données, fichiers, Active Directory, ...

Providers

Chaque provider doit permettre d'accéder à une source de données en particulier. Il fournit les différentes méthodes pour écrire / lire dans cette source. Nous allons détailler les providers un peu plus loin dans cet article.

APIs

Les APIs sont des classes qui possèdent différentes méthodes qui permettent d'effectuer certaines actions. Ces méthodes s'appuient sur le provider en action.

Contrôles de login

Alors qu'il était souvent nécessaire de réaliser son propre contrôle pour authentifier les utilisateurs ou encore manipuler les informations s'y rapportant, asp.net 2.0 a amené toute une série de contrôles le permettant.

Classe MembershipProvider: les méthodes

  • UpdateUser (Mise à jour des données d'un utilisateur)
  • CreateUser (Création d'un utilisateur)
  • DeleteUser (Suppression d'un utilisateur)
  • ValidateUser (Validation de l'inscription d'un utilisateur suite à un clic dans un email)
  • UnlockUser
  • GetUserNameByEmail (Récupération du nom de l'utilisateur en connaissant son adresse mail)
  • FindUsersByEmail/FindUsersByName (Récupération d'un objet "User" à partir d'une de ses informations)
  • ResetPassword (Génération et enregistrement d'un nouveau mot de passe)
  • ChangePassword (Mise à jour du mot de passe d'un utilisateur)
  • ...

Comme on peut le voir chaque provider doit fournir toutes les méthodes pour manipuler toutes les informations concernant un utilisateur.

On retrouve également:

  • CreateRole (Création d'un rôle)
  • DeleteRole (Suppression d'un rôle)
  • AddUserToRole (Ajout d'un rôle à un utilisateur)

Les dernières méthodes permettent de manipuler les rôles des utilisateurs. Pour cela il faut activer la gestion des rôles dans le Web.Config comme l'indique la ligne suivante:

 
Sélectionnez

<roleManager enabled=&#8220;true&#8221; />

Pour les non-adeptes des modifications dans le Web.config, je vous rassure, il est possible d'utiliser le site de configuration intégré.

Image non disponible

Pour y accéder, dans le menu Web Site, cliquez sur "asp.net website configuration".

Image non disponible

Revenons quelques instants à notre classe dérivée de MembershipProvider.

Après avoir ajouter une classe XmlMemberShipProvider, il faut la faire dériver de MemberShipProvider. Pour cela, il est nécessaire d'ajouter ": MemberShipProvider" après le nom de la classe.

Ensuite, il ne reste plus qu'à dire à Visual Studio d'implémenter toutes les méthodes de cette classe comme sur l'image suivante:

Image non disponible
 
Sélectionnez


    public override string GetPassword(string username, string answer)
    {
        // On ne gère pas la réponse

        System.IO.StreamReader sr = _
			new System.IO.StreamReader(HttpContext.Current.Server.MapPath("~/users.txt"));
        string s = sr.ReadLine();
        sr.Close();
        string[] str = s.Split(':');
        if (str[0] == username)
            return str[1];

        throw new Exception("Utilisateur inconnu");
    }

    public override MembershipUser CreateUser(string username, string password, string email, _
		string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, _
		out MembershipCreateStatus status)
    {
        System.IO.StreamWriter sw = _
			new System.IO.StreamWriter(HttpContext.Current.Server.MapPath("~/users.txt"));
        sw.WriteLine(username + ":" + password + ":" + email);
        sw.Flush();
        sw.Close();

        status = MembershipCreateStatus.Success;

        return new MembershipUser("TextMemberShipProvider", username, providerUserKey, email, _
			passwordQuestion, "", true, false, DateTime.Now, DateTime.Now, DateTime.Now, _
			DateTime.Now, DateTime.Now);
    }

    public override bool EnablePasswordRetrieval
    {
        get { return true; }
    }

    public override bool ValidateUser(string username, string password)
    {
        System.IO.StreamReader sr = _
			new System.IO.StreamReader(HttpContext.Current.Server.MapPath("~/users.txt"));
        string s = sr.ReadLine();
        string[] str = s.Split(':');
        sr.Close();
        if (str[0] == username && str[1] == password)
            return true;

        return false;
    }

Profiling

Déclaration dans le web.config

Chaque application a des besoins différents concernant les informations à garder à propos du profil d'un utilisateur. Asp.net 2.0 a ainsi amené la possibilité de définir cela dans le fichier de configuration de l'application (Web.Config).

L'exemple de déclaration dans le Web.Config qui suit permet d'indiquer qu'un "Profile" doit avoir les propriétés suivantes:

  • Theme (thème à utiliser)
  • Birthday (date d'anniversaire)
  • LoginCount (nombre d'authentifications)
 
Sélectionnez

<profile> 
	<properties> 
		<add name="Theme" /> 
		<add name="Birthday" type="System.DateTime" /> 
		<add name="LoginCount" type="System.Int32" 
		defaultValue="0" /> 
	</properties> 
</profile>

Utilisation dans le code

Après une simple compilation, la classe statique Profile est "mise à jour" et possède les différentes propriétés que l'on vient de définir dans le web.config.

On peut dès lors l'utiliser comme n'importe quelle autre propriété en utilisant l'Intellisense. On notera par ailleurs que les propriétés sont typées, ce qui signifie qu'à Birthday qui est de type DateTime, il n'est pas possible de passer un int par exemple.

 
Sélectionnez

string theme = Profile.Theme;
dateTime anniversaire = Profile.Birthday;

&#8230;

Profile.Theme = "test&#8220;;

Membership Provider

Tous les providers dérivent de la classe abstraite MembershipProvider

Image non disponible

Etant donné que la classe est dérivée,

 
Sélectionnez

TextMembershipProvider : MembershipProvider

Définition dans le web.config

De plus en plus, on tend à réaliser des applications qui demandent peu de développement en favorisant la configuration. On ne s'en plaindra pas puisqu'une application peut être adaptée très rapidement pour passer d'un provider (dans notre cas) à l'autre sans aucune recompilation.

Etant donné que Membership est géré par le framework, on retrouve un tag particulier dans le Web.Config. Il s'agit de "membership" que l'on trouve en tant que fils du noeud "system.web".

Dans la section membership, nous retrouvons les différents providers sous la forme de

 
Sélectionnez

<add name=&#8220;TextMembershipProvider" type=&#8220;TextMembershipProvider" 
	enablePasswordRetrieval=&#8220;true" enablePasswordReset=&#8220;true&#8220; 
	 &#8230; /> 

dont le contenu est simple à comprendre. Effectivement il s'agit du nom donné au Provider, la classe à utiliser pour réaliser les différentes opérations ainsi que divers paramètres permettant de spécifier quelles fonctionnalités sont fournies ou non par le provider.

Voici un exemple en utilisant le provider que nous venons de créer.

 
Sélectionnez

<system.web> 
	... 
	<membership defaultProvider=&#8220;TextMembershipProvider"> 
		<providers> 
			<add name=&#8220;TextMembershipProvider" 
			type=&#8220;TextMembershipProvider" 
			enablePasswordRetrieval=&#8220;true" 
			enablePasswordReset=&#8220;true&#8220; &#8230; /> 
		</providers> 
	</membership> 
	... 
</system.web> 

On notera également la présence de l'attribut "defaultProvider" qui permet de spécifier qu'il s'agit d'utiliser ce provider par défaut.

Conclusion

En 30 minutes nous avons réalisé un provider pour le membership. Nous avons également vu que le passage d'un provider à un autre est très simple à réaliser.

Pensez-y lors de la réalisation de vos applications. Modifier une valeur dans un Web.Config coûte moins cher à un client et amène moins de risques que de redévelopper une application complète. Ceci est évidemment valable pour tous les domaines de l'application.

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2006 Danse Didier. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.