Validation des informations d’identification de l’utilisateur par rapport au magasin d’utilisateurs d’appartenance (C#)
par Scott Mitchell
Notes
Depuis la rédaction de cet article, les fournisseurs d’appartenance ASP.NET ont été remplacés par ASP.NET Identity. Nous vous recommandons vivement de mettre à jour les applications pour utiliser la plateforme d’identité ASP.NET plutôt que les fournisseurs d’appartenance proposés au moment de la rédaction de cet article. ASP.NET Identity présente un certain nombre d’avantages par rapport au système d’appartenance ASP.NET, notamment :
- Meilleures performances
- Extensibilité et testabilité améliorées
- Prise en charge d’OAuth, OpenID Connect et de l’authentification à deux facteurs
- Prise en charge des identités basées sur les revendications
- Meilleure interopérabilité avec ASP.Net Core
Télécharger le code ou télécharger pdf
Dans ce tutoriel, nous allons examiner comment valider les informations d’identification d’un utilisateur par rapport au magasin d’utilisateurs Appartenance à l’aide de moyens programmatiques et du contrôle De connexion. Nous allons également examiner comment personnaliser l’apparence et le comportement du contrôle de connexion.
Introduction
Dans le tutoriel précédent , nous avons examiné comment créer un compte d’utilisateur dans l’infrastructure d’appartenance. Nous avons d’abord examiné la création de comptes d’utilisateur par programmation via la méthode de CreateUser
la Membership
classe, puis nous avons examiné à l’aide du contrôle Web CreateUserWizard. Toutefois, la page de connexion valide actuellement les informations d’identification fournies par rapport à une liste codée en dur de paires nom d’utilisateur et mot de passe. Nous devons mettre à jour la logique de la page de connexion afin qu’elle valide les informations d’identification par rapport au magasin d’utilisateurs de l’infrastructure d’appartenance.
Tout comme pour la création de comptes d’utilisateur, les informations d’identification peuvent être validées par programmation ou de manière déclarative. L’API Appartenance inclut une méthode permettant de valider par programmation les informations d’identification d’un utilisateur par rapport au magasin d’utilisateurs. Et ASP.NET est fourni avec le contrôle Web de connexion, qui affiche une interface utilisateur avec des zones de texte pour le nom d’utilisateur et le mot de passe et un bouton pour se connecter.
Dans ce tutoriel, nous allons examiner comment valider les informations d’identification d’un utilisateur par rapport au magasin d’utilisateurs Appartenance à l’aide de moyens programmatiques et du contrôle De connexion. Nous allons également examiner comment personnaliser l’apparence et le comportement du contrôle de connexion. C’est parti !
Étape 1 : Validation des informations d’identification par rapport au magasin d’utilisateurs d’appartenance
Pour les sites web qui utilisent l’authentification par formulaire, un utilisateur se connecte au site web en visitant une page de connexion et en entrant ses informations d’identification. Ces informations d’identification sont ensuite comparées au magasin d’utilisateurs. S’ils sont valides, l’utilisateur reçoit un ticket d’authentification par formulaire, qui est un jeton de sécurité qui indique l’identité et l’authenticité du visiteur.
Pour valider un utilisateur par rapport à l’infrastructure d’appartenance, utilisez la méthode de ValidateUser
la Membership
classe . La ValidateUser
méthode prend deux paramètres d’entrée - username
et password
- et retourne une valeur booléenne indiquant si les informations d’identification étaient valides. Comme avec la CreateUser
méthode que nous avons examinée dans le tutoriel précédent, la ValidateUser
méthode délègue la validation réelle au fournisseur d’appartenance configuré.
valide SqlMembershipProvider
les informations d’identification fournies en obtenant le mot de passe de l’utilisateur spécifié via la aspnet_Membership_GetPasswordWithFormat
procédure stockée. Rappelez-vous que le SqlMembershipProvider
stocke les mots de passe des utilisateurs à l’aide de l’un des trois formats : clair, chiffré ou haché. La aspnet_Membership_GetPasswordWithFormat
procédure stockée retourne le mot de passe dans son format brut. Pour les mots de passe chiffrés ou hachés, le SqlMembershipProvider
transforme la password
valeur passée dans la ValidateUser
méthode en son état chiffré ou haché équivalent, puis la compare à ce qui a été retourné à partir de la base de données. Si le mot de passe stocké dans la base de données correspond au mot de passe mis en forme entré par l’utilisateur, les informations d’identification sont valides.
Nous allons mettre à jour notre page de connexion (~/Login.aspx
) afin qu’elle valide les informations d’identification fournies par rapport au magasin d’utilisateurs de l’infrastructure d’appartenance. Nous avons créé cette page de connexion dans le didacticiel Vue d’ensemble de l’authentification par formulaire, créant une interface avec deux textBoxes pour le nom d’utilisateur et le mot de passe, une case à cocher Me mémoriser et un bouton Connexion (voir figure 1). Le code valide les informations d’identification entrées par rapport à une liste codée en dur de paires nom d’utilisateur et mot de passe (Scott/password, Jisun/password et Sam/password).
Figure 1 : L’interface de la page de connexion comprend deux zones de texte, un CheckBoxList et un bouton (cliquer pour afficher l’image en taille réelle)
L’interface utilisateur de la page de connexion peut rester inchangée, mais nous devons remplacer le gestionnaire d’événements du Click
bouton De connexion par du code qui valide l’utilisateur par rapport au magasin d’utilisateurs de l’infrastructure d’appartenance. Mettez à jour le gestionnaire d’événements afin que son code s’affiche comme suit :
protected void LoginButton_Click(object sender, EventArgs e)
{
// Validate the user against the Membership framework user store
if (Membership.ValidateUser(UserName.Text, Password.Text))
{
// Log the user into the site
FormsAuthentication.RedirectFromLoginPage(UserName.Text, RememberMe.Checked);
}
// If we reach here, the user's credentials were invalid
InvalidCredentialsMessage.Visible = true;
}
Ce code est remarquablement simple. Nous commençons par appeler la Membership.ValidateUser
méthode, en transmettant le nom d’utilisateur et le mot de passe fournis. Si cette méthode retourne true, l’utilisateur est connecté au site via la méthode RedirectFromLoginPage de la FormsAuthentication
classe. (Comme nous l’avons vu dans le Tutoriel Vue d’ensemble de l’authentificationFormsAuthentication.RedirectFromLoginPage
par formulaire, crée le ticket d’authentification par formulaire, puis redirige l’utilisateur vers la page appropriée.) Si les informations d’identification ne sont pas valides, l’étiquette InvalidCredentialsMessage
s’affiche, informant l’utilisateur que son nom d’utilisateur ou son mot de passe était incorrect.
C’est tout !
Pour vérifier que la page de connexion fonctionne comme prévu, essayez de vous connecter avec l’un des comptes d’utilisateur que vous avez créés dans le tutoriel précédent. Ou, si vous n’avez pas encore créé de compte, continuez et créez-en un à partir de la ~/Membership/CreatingUserAccounts.aspx
page.
Notes
Lorsque l’utilisateur entre ses informations d’identification et envoie le formulaire de page de connexion, les informations d’identification, y compris son mot de passe, sont transmises via Internet au serveur web en texte brut. Cela signifie que tout pirate reniflant le trafic réseau peut voir le nom d’utilisateur et le mot de passe. Pour éviter cela, il est essentiel de chiffrer le trafic réseau à l’aide de ssl (Secure Socket Layer). Cela garantit que les informations d’identification (ainsi que le balisage HTML de la page entière) sont chiffrées à partir du moment où elles quittent le navigateur jusqu’à ce qu’elles soient reçues par le serveur web.
Comment l’infrastructure d’appartenance gère les tentatives de connexion non valides
Lorsqu’un visiteur atteint la page de connexion et envoie ses informations d’identification, son navigateur effectue une requête HTTP à la page de connexion. Si les informations d’identification sont valides, la réponse HTTP inclut le ticket d’authentification dans un cookie. Par conséquent, un pirate qui tente de pénétrer dans votre site peut créer un programme qui envoie de manière exhaustive des requêtes HTTP à la page de connexion avec un nom d’utilisateur valide et une estimation du mot de passe. Si l’estimation du mot de passe est correcte, la page de connexion retourne le cookie de ticket d’authentification, auquel cas le programme sait qu’il est tombé sur une paire nom d’utilisateur/mot de passe valide. Par force brute, un tel programme peut être en mesure de tomber sur le mot de passe d’un utilisateur, en particulier si le mot de passe est faible.
Pour empêcher de telles attaques par force brute, l’infrastructure d’appartenance verrouille un utilisateur s’il y a un certain nombre de tentatives de connexion infructueuses dans un certain laps de temps. Les paramètres exacts sont configurables via les deux paramètres de configuration du fournisseur d’appartenance suivants :
maxInvalidPasswordAttempts
- spécifie le nombre de tentatives de mot de passe non valides autorisées pour l’utilisateur au cours de la période précédant le verrouillage du compte. La valeur par défaut est 5.passwordAttemptWindow
- indique la période en minutes pendant laquelle le nombre spécifié de tentatives de connexion non valides entraîne le verrouillage du compte. La valeur par défaut est 10.
Si un utilisateur a été verrouillé, il ne peut pas se connecter tant qu’un administrateur n’a pas déverrouillé son compte. Lorsqu’un utilisateur est verrouillé, la ValidateUser
méthode retourne false
toujours , même si des informations d’identification valides sont fournies. Bien que ce comportement diminue la probabilité qu’un pirate s’insèrent dans votre site par le biais de méthodes de force brute, il peut finir par verrouiller un utilisateur valide qui a simplement oublié son mot de passe ou a accidentellement le verrouillage des majuscules ou a une mauvaise journée de saisie.
Malheureusement, il n’existe aucun outil intégré pour déverrouiller un compte d’utilisateur. Pour déverrouiller un compte, vous pouvez modifier la base de données directement ( modifier le IsLockedOut
champ dans la aspnet_Membership
table du compte d’utilisateur approprié) ou créer une interface web qui répertorie les comptes verrouillés avec des options pour les déverrouiller. Nous examinerons la création d’interfaces d’administration pour accomplir des tâches courantes liées aux comptes d’utilisateur et aux rôles dans un prochain tutoriel.
Notes
L’un des inconvénients de la ValidateUser
méthode est que lorsque les informations d’identification fournies ne sont pas valides, elle ne fournit aucune explication quant à la raison. Les informations d’identification peuvent être non valides parce qu’il n’existe aucune paire nom d’utilisateur/mot de passe correspondante dans le magasin d’utilisateurs, ou parce que l’utilisateur n’a pas encore été approuvé ou parce que l’utilisateur a été verrouillé. À l’étape 4, nous verrons comment afficher un message plus détaillé à l’utilisateur en cas d’échec de sa tentative de connexion.
Étape 2 : Collecte des informations d’identification via le contrôle Web de connexion
Le contrôle Web de connexion affiche une interface utilisateur par défaut très similaire à celle que nous avons créée dans le didacticiel Vue d’ensemble de l’authentification par formulaire. L’utilisation du contrôle Connexion nous évite de devoir créer l’interface pour collecter les informations d’identification du visiteur. En outre, le contrôle de connexion connecte automatiquement l’utilisateur (en supposant que les informations d’identification soumises sont valides), ce qui nous évite d’avoir à écrire du code.
Mettons à jour Login.aspx
, en remplaçant l’interface et le code créés manuellement par un contrôle De connexion. Commencez par supprimer le balisage et le code existants dans Login.aspx
. Vous pouvez le supprimer purement et simplement ou le commenter. Pour commenter le balisage déclaratif, entourez-le <%--
des délimiteurs et --%>
. Vous pouvez entrer ces délimiteurs manuellement ou, comme le montre la figure 2, vous pouvez sélectionner le texte à commenter, puis cliquer sur l’icône Commenter les lignes sélectionnées dans la barre d’outils. De même, vous pouvez utiliser l’icône Commenter les lignes sélectionnées pour commenter le code sélectionné dans la classe code-behind.
Figure 2 : Commentez le balisage déclaratif et le code source existants dans Login.aspx
(cliquez pour afficher l’image en taille réelle)
Notes
L’icône Commenter les lignes sélectionnées n’est pas disponible lors de l’affichage du balisage déclaratif dans Visual Studio 2005. Si vous n’utilisez pas Visual Studio 2008, vous devez ajouter manuellement les <%--
délimiteurs et .--%>
Ensuite, faites glisser un contrôle de connexion de la boîte à outils sur la page et définissez sa ID
propriété myLogin
sur . À ce stade, votre écran doit ressembler à la figure 3. Notez que l’interface par défaut du contrôle De connexion comprend des contrôles TextBox pour le nom d’utilisateur et le mot de passe, un checkBox se souvenir de la prochaine fois et un bouton De connexion. Il existe également RequiredFieldValidator
des contrôles pour les deux Zones de texte.
Figure 3 : Ajouter un contrôle de connexion à la page (cliquer pour afficher l’image en taille réelle)
Et c’est fini ! Lorsque vous cliquez sur le bouton d’ouverture de session du contrôle de connexion, une publication se produit et le contrôle de connexion appelle la Membership.ValidateUser
méthode, en passant le nom d’utilisateur et le mot de passe entrés. Si les informations d’identification ne sont pas valides, le contrôle De connexion affiche un message indiquant ce type. Si, toutefois, les informations d’identification sont valides, le contrôle De connexion crée le ticket d’authentification par formulaire et redirige l’utilisateur vers la page appropriée.
Le contrôle de connexion utilise quatre facteurs pour déterminer la page appropriée vers laquelle rediriger l’utilisateur lors d’une connexion réussie :
- Si le contrôle de connexion se trouve sur la page de connexion comme défini par le paramètre dans la configuration d’authentification par
loginUrl
formulaire ; la valeur par défaut de ce paramètre estLogin.aspx
- Présence d’un
ReturnUrl
paramètre de chaîne de requête - Valeur de la propriété du contrôle De
DestinationUrl
connexion - Valeur
defaultUrl
spécifiée dans les paramètres de configuration de l’authentification par formulaire ; la valeur par défaut de ce paramètre estDefault.aspx
La figure 4 montre comment le contrôle De connexion utilise ces quatre paramètres pour arriver à sa décision de page appropriée.
Figure 4 : Ajouter un contrôle de connexion à la page (cliquer pour afficher l’image en taille réelle)
Prenez un moment pour tester le contrôle de connexion en visitant le site via un navigateur et en vous connectant en tant qu’utilisateur existant dans l’infrastructure d’appartenance.
L’interface rendue du contrôle de connexion est hautement configurable. Il existe un certain nombre de propriétés qui influencent son apparence; De plus, le contrôle de connexion peut être converti en modèle pour un contrôle précis sur la disposition des éléments de l’interface utilisateur. Le reste de cette étape examine comment personnaliser l’apparence et la disposition.
Personnalisation de l’apparence du contrôle de connexion
Les paramètres de propriété par défaut du contrôle De connexion affichent une interface utilisateur avec un titre ( Se connecter), des contrôles TextBox et Étiquette pour les entrées de nom d’utilisateur et de mot de passe, un checkBox se souvenir de la prochaine fois et un bouton Se connecter. Les apparences de ces éléments sont toutes configurables via les nombreuses propriétés du contrôle De connexion. En outre, d’autres éléments d’interface utilisateur, tels qu’un lien vers une page pour créer un compte d’utilisateur, peuvent être ajoutés en définissant une ou deux propriétés.
Passons quelques instants à nous occuper de l’apparence de notre contrôle de connexion. Étant donné que la Login.aspx
page contient déjà un texte en haut de la page qui indique Connexion, le titre du contrôle De connexion est superflu. Par conséquent, effacez la valeur de laTitleText
propriété afin de supprimer le titre du contrôle Login.
Les étiquettes Nom d’utilisateur : et Mot de passe : à gauche des deux contrôles TextBox peuvent être personnalisées via les UserNameLabelText
propriétés etPasswordLabelText
, respectivement. Nous allons modifier le nom d’utilisateur : étiquette pour lire Nom d’utilisateur : . Les styles Label et TextBox sont configurables via les LabelStyle
propriétés etTextBoxStyle
, respectivement.
La prochaine fois que la propriété Text de CheckBox peut être définie par le biais du RememberMeText property
contrôle Login, son état vérifié par défaut est configurable via ( RememberMeSet property
qui prend la valeur False par défaut). Continuez et définissez la propriété sur RememberMeSet
True afin que la prochaine fois que CheckBox soit vérifiée par défaut.
Le contrôle Login offre deux propriétés pour ajuster la disposition de ses contrôles d’interface utilisateur. indique TextLayout property
si les étiquettes Nom d’utilisateur : et Mot de passe : apparaissent à gauche de leurs TextBox correspondantes (valeur par défaut) ou au-dessus d’eux. indique Orientation property
si les entrées de nom d’utilisateur et de mot de passe sont situées verticalement (l’une au-dessus de l’autre) ou horizontalement. Je vais laisser ces deux propriétés définies sur leurs valeurs par défaut, mais je vous encourage à essayer de définir ces deux propriétés sur leurs valeurs non par défaut pour voir l’effet résultant.
Notes
Dans la section suivante, Configuration de la disposition du contrôle de connexion, nous allons examiner l’utilisation de modèles pour définir la disposition précise des éléments d’interface utilisateur du contrôle Layout.
Terminez les paramètres de propriété du contrôle de connexion en définissant les CreateUserText
propriétés et CreateUserUrl
sur Non encore inscrit ? Créez un compte ! et ~/Membership/CreatingUserAccounts.aspx
, respectivement. Cela ajoute un lien hypertexte à l’interface du contrôle De connexion pointant vers la page que nous avons créée dans le tutoriel précédent. Les propriétés et les HelpPageUrl
propriétés du HelpPageText
contrôle de connexion et PasswordRecoveryText
les propriétés fonctionnent PasswordRecoveryUrl
de la même manière, ce qui rend les liens vers une page d’aide et une page de récupération de mot de passe.
Après avoir apporté ces modifications à la propriété, le balisage déclaratif et l’apparence de votre contrôle de connexion doivent ressembler à ceux de la figure 5.
Figure 5 : Les valeurs des propriétés du contrôle de connexion déterminent son apparence (cliquez pour afficher l’image en taille réelle)
Configuration de la disposition du contrôle de connexion
L’interface utilisateur par défaut du contrôle Web de connexion présente l’interface dans un code HTML <table>
. Mais que se passe-t-il si nous avons besoin d’un contrôle plus précis sur la sortie rendue ? Peut-être voulons-nous remplacer par <table>
une série d’étiquettes <div>
. Ou que se passe-t-il si notre application nécessite des informations d’identification supplémentaires pour l’authentification ? De nombreux sites web financiers, par instance, exigent que les utilisateurs fournissent non seulement un nom d’utilisateur et un mot de passe, mais également un numéro d’identification personnel (PIN) ou d’autres informations d’identification. Quelles que soient les raisons, il est possible de convertir le contrôle De connexion en modèle, à partir duquel nous pouvons définir explicitement le balisage déclaratif de l’interface.
Nous devons effectuer deux opérations pour mettre à jour le contrôle de connexion afin de collecter des informations d’identification supplémentaires :
- Mettez à jour l’interface du contrôle de connexion pour inclure le ou les contrôles Web afin de collecter les informations d’identification supplémentaires.
- Remplacez la logique d’authentification interne du contrôle de connexion afin qu’un utilisateur soit authentifié uniquement si son nom d’utilisateur et son mot de passe sont valides et si ses informations d’identification supplémentaires sont également valides.
Pour accomplir la première tâche, nous devons convertir le contrôle de connexion en modèle et ajouter les contrôles Web nécessaires. Comme pour la deuxième tâche, la logique d’authentification du contrôle de connexion peut être remplacée en créant un gestionnaire d’événements pour l’événement du Authenticate
contrôle.
Nous allons mettre à jour le contrôle de connexion afin qu’il invite les utilisateurs à entrer leur nom d’utilisateur, leur mot de passe et leur adresse e-mail et qu’il authentifie uniquement l’utilisateur si l’adresse e-mail fournie correspond à leur adresse e-mail dans le fichier. Nous devons d’abord convertir l’interface du contrôle de connexion en modèle. Dans la balise active du contrôle de connexion, choisissez l’option Convertir en modèle.
Figure 6 : Convertir le contrôle de connexion en modèle (cliquer pour afficher l’image en taille réelle)
Notes
Pour rétablir la version du pré-modèle du contrôle De connexion, cliquez sur le lien Réinitialiser à partir de la balise intelligente du contrôle.
La conversion du contrôle de connexion en modèle ajoute un LayoutTemplate
au balisage déclaratif du contrôle avec des éléments HTML et des contrôles Web définissant l’interface utilisateur. Comme le montre la figure 7, la conversion du contrôle en modèle supprime un certain nombre de propriétés du Fenêtre Propriétés, telles que TitleText
, CreateUserUrl
et ainsi de suite, car ces valeurs de propriété sont ignorées lors de l’utilisation d’un modèle.
Figure 7 : Moins de propriétés sont disponibles lorsque le contrôle de connexion est converti en modèle (cliquez pour afficher l’image de taille réelle)
Le balisage HTML dans peut LayoutTemplate
être modifié en fonction des besoins. De même, n’hésitez pas à ajouter de nouveaux contrôles Web au modèle. Toutefois, il est important que les principaux contrôles Web du contrôle de connexion restent dans le modèle et conservent les valeurs qui leur sont attribuées ID
. En particulier, ne supprimez pas ou ne renommez pas les UserName
Password
TextBox ou, le RememberMe
CheckBox, le LoginButton
Button, l’Étiquette FailureText
ou les RequiredFieldValidator
contrôles.
Pour collecter l’adresse e-mail du visiteur, nous devons ajouter une zone de texte au modèle. Ajoutez le balisage déclaratif suivant entre la ligne de table (<tr>
) qui contient la Password
zone de texte et la ligne de table qui contient la case à cocher Se souvenir de la prochaine fois :
<tr>
<td align="right">
<asp:Label ID="EmailLabel" runat="server" AssociatedControlID="Email">Email:</asp:Label>
</td>
<td>
<asp:TextBox ID="Email" runat="server"></asp:TextBox>
<asp:RequiredFieldValidator ID="EmailRequired" runat="server"
ControlToValidate="Email" ErrorMessage="Email is required."
ToolTip="Email is required." ValidationGroup="myLogin">*</asp:RequiredFieldValidator>
</td>
</tr>
Après avoir ajouté la Email
zone de texte, accédez à la page via un navigateur. Comme le montre la figure 8, l’interface utilisateur du contrôle de connexion comprend désormais une troisième zone de texte.
Figure 8 : Le contrôle de connexion inclut désormais une zone de texte pour l’adresse Email de l’utilisateur (cliquer pour afficher l’image en taille réelle)
À ce stade, le contrôle de connexion utilise toujours la Membership.ValidateUser
méthode pour valider les informations d’identification fournies. En conséquence, la valeur entrée dans la Email
zone de texte n’a aucune incidence sur la possibilité pour l’utilisateur de se connecter. À l’étape 3, nous allons voir comment remplacer la logique d’authentification du contrôle de connexion afin que les informations d’identification soient considérées comme valides uniquement si le nom d’utilisateur et le mot de passe sont valides et si l’adresse e-mail fournie correspond à l’adresse e-mail dans le fichier.
Étape 3 : Modification de la logique d’authentification du contrôle de connexion
Lorsqu’un visiteur fournit ses informations d’identification et clique sur le bouton Se connecter, une publication s’ensuit et le contrôle de connexion progresse dans son flux de travail d’authentification. Le workflow commence par déclencher l’événementLoggingIn
. Tous les gestionnaires d’événements associés à cet événement peuvent annuler l’opération de connexion en définissant la e.Cancel
propriété sur true
.
Si l’opération de connexion n’est pas annulée, le flux de travail progresse en déclenchant l’événementAuthenticate
. S’il existe un gestionnaire d’événements pour l’événement Authenticate
, il est chargé de déterminer si les informations d’identification fournies sont valides ou non. Si aucun gestionnaire d’événements n’est spécifié, le contrôle Login utilise la Membership.ValidateUser
méthode pour déterminer la validité des informations d’identification.
Si les informations d’identification fournies sont valides, le ticket d’authentification par formulaire est créé, l’événementLoggedIn
est déclenché et l’utilisateur est redirigé vers la page appropriée. Si, toutefois, les informations d’identification sont considérées comme non valides, l’événementLoginError
est déclenché et un message s’affiche pour informer l’utilisateur que ses informations d’identification n’étaient pas valides. Par défaut, en cas d’échec, le contrôle de connexion définit simplement la propriété Text de son FailureText
contrôle Label sur un message d’échec ( Votre tentative de connexion n’a pas réussi. Réessayez . Toutefois, si la propriété du FailureAction
contrôle de connexion est définie sur RedirectToLoginPage
, le contrôle de connexion émet un Response.Redirect
sur la page de connexion en ajoutant le paramètre loginfailure=1
de chaîne de requête (ce qui entraîne l’affichage du message d’échec par le contrôle Login).
La figure 9 présente un organigramme du flux de travail d’authentification.
Figure 9 : Flux de travail d’authentification du contrôle de connexion (cliquez pour afficher l’image en taille réelle)
Notes
Si vous vous demandez quand vous utiliserez l’option FailureAction
de page de RedirectToLogin
, envisagez le scénario suivant. À l’heure actuelle, notre Site.master
page master contient le texte Hello, étranger affiché dans la colonne de gauche lorsqu’un utilisateur anonyme visite, mais imaginez que nous voulions remplacer ce texte par un contrôle De connexion. Cela permettrait à un utilisateur anonyme de se connecter à partir de n’importe quelle page du site, au lieu de lui demander de visiter directement la page de connexion. Toutefois, si un utilisateur n’a pas pu se connecter via le contrôle de connexion rendu par la page master, il peut être judicieux de le rediriger vers la page de connexion (Login.aspx
) car cette page inclut probablement des instructions supplémentaires, des liens et d’autres informations (par exemple, des liens pour créer un compte ou récupérer un mot de passe perdu) qui n’ont pas été ajoutés à la page master.
Création du gestionnaire d’événementsAuthenticate
Pour brancher notre logique d’authentification personnalisée, nous devons créer un gestionnaire d’événements pour l’événement du contrôle de Authenticate
connexion. La création d’un gestionnaire d’événements pour l’événement Authenticate
génère la définition de gestionnaire d’événements suivante :
protected void myLogin_Authenticate(object sender, AuthenticateEventArgs e)
{
}
Comme vous pouvez le voir, le Authenticate
gestionnaire d’événements passe un objet de type AuthenticateEventArgs
comme deuxième paramètre d’entrée. La AuthenticateEventArgs
classe contient une propriété booléenne nommée Authenticated
qui est utilisée pour spécifier si les informations d’identification fournies sont valides. Notre tâche consiste donc à écrire ici du code qui détermine si les informations d’identification fournies sont valides ou non, et à définir la e.Authenticate
propriété en conséquence.
Détermination et validation des informations d’identification fournies
Utilisez les propriétés et Password
du contrôle De UserName
connexion pour déterminer les informations d’identification de nom d’utilisateur et de mot de passe entrées par l’utilisateur. Pour déterminer les valeurs entrées dans tous les contrôles Web supplémentaires (par exemple, textBox Email
que nous avons ajouté à l’étape précédente), utilisez LoginControlID
.FindControl
( »controlID
« ) pour obtenir une référence programmatique au contrôle Web dans le modèle dont ID
la propriété est égale à controlID
. Par exemple, pour obtenir une référence à TextBox Email
, utilisez le code suivant :
TextBox EmailTextBox = myLogin.FindControl("Email") as TextBox;
Pour valider les informations d’identification de l’utilisateur, nous devons effectuer deux opérations :
- Vérifiez que le nom d’utilisateur et le mot de passe fournis sont valides
- Vérifiez que l’adresse e-mail entrée correspond à l’adresse e-mail dans le fichier pour l’utilisateur qui tente de se connecter
Pour accomplir la première case activée nous pouvons simplement utiliser la Membership.ValidateUser
méthode comme nous l’avons vu à l’étape 1. Pour la deuxième case activée, nous devons déterminer l’adresse e-mail de l’utilisateur afin de pouvoir la comparer à l’adresse e-mail qu’il a entrée dans le contrôle TextBox. Pour obtenir des informations sur un utilisateur particulier, utilisez la méthode de la Membership
GetUser
classe .
La GetUser
méthode comporte un certain nombre de surcharges. S’il est utilisé sans passer de paramètres, il retourne des informations sur l’utilisateur actuellement connecté. Pour obtenir des informations sur un utilisateur particulier, appelez GetUser
en passant son nom d’utilisateur. Dans les deux cas, GetUser
retourne un MembershipUser
objet, qui a des propriétés telles que UserName
, Email
, IsApproved
, IsOnline
, et ainsi de suite.
Le code suivant implémente ces deux vérifications. Si les deux passent, est e.Authenticate
défini sur true
, sinon il est affecté false
.
protected void myLogin_Authenticate(object sender, AuthenticateEventArgs e)
{
// Get the email address entered
TextBox EmailTextBox = myLogin.FindControl("Email") as TextBox;
string email = EmailTextBox.Text.Trim();
// Verify that the username/password pair is valid
if (Membership.ValidateUser(myLogin.UserName, myLogin.Password))
{
// Username/password are valid, check email
MembershipUser usrInfo = Membership.GetUser(myLogin.UserName);
if (usrInfo != null && string.Compare(usrInfo.Email, email, true) == 0)
{
// Email matches, the credentials are valid
e.Authenticated = true;
}
else
{
// Email address is invalid...
e.Authenticated = false;
}
}
else
{
// Username/password are not valid...
e.Authenticated = false;
}
}
Une fois ce code en place, essayez de vous connecter en tant qu’utilisateur valide, en entrant le nom d’utilisateur, le mot de passe et l’adresse e-mail corrects. Réessayez, mais utilisez cette fois une adresse e-mail incorrecte (voir la figure 10). Enfin, essayez-le une troisième fois à l’aide d’un nom d’utilisateur inexistant. Dans le premier cas, vous devez être correctement connecté au site, mais dans les deux derniers cas, vous devez voir le message d’informations d’identification non valides du contrôle de connexion.
Figure 10 : Tito ne peut pas se connecter lors de la fourniture d’une adresse de Email incorrecte (cliquez pour afficher l’image en taille réelle)
Notes
Comme indiqué dans la section Comment l’infrastructure d’appartenance gère les tentatives de connexion non valides à l’étape 1, lorsque la Membership.ValidateUser
méthode est appelée et passe des informations d’identification non valides, elle effectue le suivi de la tentative de connexion non valide et verrouille l’utilisateur si elles dépassent un certain seuil de tentatives non valides dans une fenêtre de temps spécifiée. Étant donné que notre logique d’authentification personnalisée appelle la ValidateUser
méthode, un mot de passe incorrect pour un nom d’utilisateur valide incrémente le compteur de tentative de connexion non valide, mais ce compteur n’est pas incrémenté dans le cas où le nom d’utilisateur et le mot de passe sont valides, mais l’adresse e-mail est incorrecte. Il est probable que ce comportement convienne, car il est peu probable qu’un pirate connaisse le nom d’utilisateur et le mot de passe, mais qu’il doit utiliser des techniques de force brute pour déterminer l’adresse e-mail de l’utilisateur.
Étape 4 : Amélioration du message d’informations d’identification non valides du contrôle de connexion
Lorsqu’un utilisateur tente de se connecter avec des informations d’identification non valides, le contrôle Connexion affiche un message expliquant que la tentative de connexion a échoué. En particulier, le contrôle affiche le message spécifié par sa FailureText
propriété, qui a la valeur par défaut Votre tentative de connexion n’a pas réussi. Recommencez.
Rappelez-vous qu’il existe de nombreuses raisons pour lesquelles les informations d’identification d’un utilisateur peuvent être non valides :
- Le nom d’utilisateur n’existe peut-être pas
- Le nom d’utilisateur existe, mais le mot de passe n’est pas valide
- Le nom d’utilisateur et le mot de passe sont valides, mais l’utilisateur n’est pas encore approuvé
- Le nom d’utilisateur et le mot de passe sont valides, mais l’utilisateur est verrouillé (probablement parce qu’ils ont dépassé le nombre de tentatives de connexion non valides dans le délai spécifié)
Et il peut y avoir d’autres raisons lors de l’utilisation de la logique d’authentification personnalisée. Par exemple, avec le code que nous avons écrit à l’étape 3, le nom d’utilisateur et le mot de passe peuvent être valides, mais l’adresse e-mail peut être incorrecte.
Quelle que soit la raison pour laquelle les informations d’identification ne sont pas valides, le contrôle Connexion affiche le même message d’erreur. Ce manque de commentaires peut prêter à confusion pour un utilisateur dont le compte n’a pas encore été approuvé ou qui a été verrouillé. Toutefois, avec un peu de travail, nous pouvons faire en sorte que le contrôle De connexion affiche un message plus approprié.
Chaque fois qu’un utilisateur tente de se connecter avec des informations d’identification non valides, le contrôle De connexion déclenche son LoginError
événement. Créez un gestionnaire d’événements pour cet événement et ajoutez le code suivant :
protected void myLogin_LoginError(object sender, EventArgs e)
{
// Determine why the user could not login...
myLogin.FailureText = "Your login attempt was not successful. Please try again.";
// Does there exist a User account for this user?
MembershipUser usrInfo = Membership.GetUser(myLogin.UserName);
if (usrInfo != null)
{
// Is this user locked out?
if (usrInfo.IsLockedOut)
{
myLogin.FailureText = "Your account has been locked out because of too many invalid login attempts. Please contact the administrator to have your account unlocked.";
}
else if (!usrInfo.IsApproved)
{
myLogin.FailureText = "Your account has not yet been approved. You cannot login until an administrator has approved your account.";
}
}
}
Le code ci-dessus commence par définir la propriété du FailureText
contrôle De connexion sur la valeur par défaut ( Votre tentative de connexion n’a pas réussi. Veuillez réessayer ). Il vérifie ensuite si le nom d’utilisateur fourni correspond à un compte d’utilisateur existant. Dans ce cas, il consulte les propriétés et IsApproved
de l’objet IsLockedOut
résultant MembershipUser
pour déterminer si le compte a été verrouillé ou n’a pas encore été approuvé. Dans les deux cas, la FailureText
propriété est mise à jour vers une valeur correspondante.
Pour tester ce code, essayez délibérément de vous connecter en tant qu’utilisateur existant, mais utilisez un mot de passe incorrect. Effectuez cette opération cinq fois de suite dans un laps de temps de 10 minutes et le compte sera verrouillé. Comme le montre la figure 11, les tentatives de connexion suivantes échouent toujours (même avec le mot de passe correct), mais affichent désormais le plus descriptif Votre compte a été verrouillé en raison d’un trop grand nombre de tentatives de connexion non valides. Contactez l’administrateur pour que votre compte soit déverrouillé.
Figure 11 : Tito a effectué trop de tentatives de connexion non valides et a été verrouillé (cliquez pour afficher l’image en taille réelle)
Résumé
Avant ce tutoriel, notre page de connexion validait les informations d’identification fournies par rapport à une liste codée en dur de paires nom d’utilisateur/mot de passe. Dans ce tutoriel, nous avons mis à jour la page pour valider les informations d’identification par rapport à l’infrastructure d’appartenance. À l’étape 1, nous avons examiné l’utilisation de la Membership.ValidateUser
méthode par programmation. À l’étape 2, nous avons remplacé notre interface utilisateur et notre code créés manuellement par le contrôle Connexion.
Le contrôle Connexion affiche une interface utilisateur de connexion standard et valide automatiquement les informations d’identification de l’utilisateur par rapport à l’infrastructure d’appartenance. En outre, en cas d’informations d’identification valides, le contrôle Connexion connecte l’utilisateur via l’authentification par formulaire. En bref, une expérience utilisateur de connexion entièrement fonctionnelle est disponible en faisant simplement glisser le contrôle Connexion sur une page, sans balisage déclaratif supplémentaire ni code nécessaire. De plus, le contrôle De connexion est hautement personnalisable, ce qui permet un degré de contrôle précis à la fois sur l’interface utilisateur rendue et la logique d’authentification.
À ce stade, les visiteurs de notre site web peuvent créer un compte d’utilisateur et se connecter au site, mais nous n’avons pas encore examiné la restriction de l’accès aux pages en fonction de l’utilisateur authentifié. Actuellement, n’importe quel utilisateur, authentifié ou anonyme, peut afficher n’importe quelle page sur notre site. Outre le contrôle de l’accès aux pages de notre site par utilisateur, nous pouvons avoir certaines pages dont les fonctionnalités dépendent de l’utilisateur. Le tutoriel suivant montre comment limiter l’accès et les fonctionnalités dans la page en fonction de l’utilisateur connecté.
Bonne programmation!
En savoir plus
Pour plus d’informations sur les sujets abordés dans ce didacticiel, consultez les ressources suivantes :
- Affichage de messages personnalisés pour les utilisateurs verrouillés et non approuvés
- Examen de l’appartenance, des rôles et du profil de ASP.NET 2.0
- Procédure : créer une page de connexion ASP.NET
- Documentation technique sur le contrôle de connexion
- Utilisation des contrôles de connexion
À propos de l’auteur
Scott Mitchell, auteur de plusieurs livres ASP/ASP.NET et fondateur de 4GuysFromRolla.com, travaille avec les technologies Web Microsoft depuis 1998. Scott travaille comme consultant indépendant, formateur et écrivain. Son dernier livre est Sams Teach Yourself ASP.NET 2.0 in 24 Hours. Scott peut être joint à l’adresse mitchell@4guysfromrolla.com ou via son blog à l’adresse http://ScottOnWriting.NET.
Remerciements spéciaux à
Cette série de tutoriels a été examinée par de nombreux réviseurs utiles. Les réviseurs principaux de ce tutoriel étaient Teresa Murphy et Michael Olivero. Vous souhaitez consulter mes prochains articles MSDN ? Si c’est le cas, déposez-moi une ligne à mitchell@4GuysFromRolla.com.