Auteur : Willmove et& Heath Stewart
Page d'accueil : http://www.amuhouse.com
Courriel : [email protected]
Remarque : je viens d'apprendre ASP.NET il y a deux mois. J'ai vu un article intitulé Sécurité basée sur les rôles avec authentification par formulaires sur codeproject.com et je l'ai trouvé très utile. A cette époque, je voulais le traduire en chinois. Cependant, la traduction directe est vraiment ennuyeuse. Au cours des deux derniers jours, j'ai fait référence à cet article de Heath Stewart et, sur la base de ma propre compréhension, je l'ai écrit en chinois selon mes propres idées et expressions. Vous trouverez ci-joint une application Web de démonstration que j'ai créée pour cet article.
En cas de malentendu, veuillez nous écrire pour le signaler ou laisser un commentaire.
P.S. Le spam est vraiment ennuyeux, montrez votre respect.
L'article original se trouve sur http://www.codeproject.com/aspnet/formsroleauth.asp
Auteur originalHeath Stewart
résumé:
ASP.NET fournit un mécanisme d'authentification basé sur les rôles, mais sa prise en charge des rôles est incomplète. Cet article tente d'illustrer comment implémenter et utiliser ce mécanisme d'authentification basée sur les rôles à travers quelques exemples.
Introduction :
L'authentification par formulaire dans ASP.NET est une fonctionnalité très puissante qui ne nécessite qu'une petite quantité de code pour implémenter un système d'authentification de sécurité simple et indépendant de la plate-forme.
Toutefois, si vous avez besoin d'un mécanisme d'authentification plus complexe et plus efficace, vous devrez alors tirer parti de sa flexibilité en divisant de nombreux utilisateurs en groupes d'utilisateurs. L'authentification intégrée Windows fournit ce mécanisme d'authentification, mais elle utilise NTLM, le gestionnaire LAN de Windows NT, et n'est donc pas multiplateforme. Aujourd'hui, de plus en plus de personnes utilisent les systèmes Linux et il y a de plus en plus d'utilisateurs du navigateur Mozilla Forefox. Nous ne pouvons certainement pas empêcher ces personnes d'entrer, nous recherchons donc un autre mécanisme d'authentification. Il existe deux options : l'une consiste à diviser le site Web en plusieurs zones et à fournir plusieurs pages de connexion, obligeant les utilisateurs à s'inscrire et à se connecter un par un ; l'autre consiste à regrouper les utilisateurs et à restreindre les droits d'accès de groupes d'utilisateurs spécifiques à une certaine page ; ou la région. Ce dernier est certainement le meilleur choix. Nous pouvons réaliser cette fonctionnalité en attribuant des rôles à des utilisateurs individuels.
Microsoft a laissé le mécanisme d'authentification basée sur les rôles dans l'authentification par formulaire pour la plate-forme .NET, mais nous devons l'implémenter nous-mêmes. Cet article s'efforce de couvrir quelques éléments de base sur le mécanisme d'authentification basée sur les rôles dans l'authentification par formulaire, tels que son concept, sa mise en œuvre, comment l'appliquer dans les applications Web, etc.
Préparation nécessaire :
Il faut d'abord créer une base de données, un projet d'application Web, plusieurs répertoires confidentiels avec différents niveaux de sécurité et plusieurs pages ASP.NET. Bien entendu, vous pouvez également les ajouter à votre projet d'application Web existant.
1. Pour créer une base de données,
vous devez d'abord choisir le système de gestion de base de données SGBD que vous souhaitez utiliser. Cet article utilise SQL Server 2000.
Dans la base de données des projets d'application réels, il existe généralement une table de données utilisateur Utilisateurs, qui peut inclure la balise unique de l'utilisateur : UserID, le nom d'utilisateur : UserName, le mot de passe : Mot de passe, l'adresse e-mail de l'utilisateur : Email, la ville de l'utilisateur : City et le numéro de connexions utilisateur LoginCount etc. Vous pouvez attribuer des rôles aux utilisateurs en créant une table de données UserInRoles (comprenant généralement deux champs, nom d'utilisateur : UserName, rôle d'utilisateur : UserRoles).
Par souci de simplicité, je crée uniquement une table de données Utilisateurs, qui comporte 3 champs, le nom d'utilisateur UserName, le mot de passe Mot de passe et les rôles d'utilisateur UserRoles. Avant de créer une table, vous devez sélectionner une base de données ou créer une nouvelle base de données. Pour créer une nouvelle base de données nommée WebSolution, seule une simple instruction SQL est requise :
code de programme
Créer une solution Web de base de données
Pour sélectionner une base de données appelée msdb
dans GO
, vous pouvez utiliser l'instruction SQL :
code de programme
UTILISER msdb
ALLER
Ensuite, nous créons la table de données Users que nous venons de mentionner. Le script SQL est le suivant :
Code du programme
Create TABLE Users.
(
Nom d'utilisateur nvarchar(100) CONTRAINTE PK_UserName CLÉ PRIMAIRE,
Mot de passe nvarchar(150),
Rôles utilisateur nvarchar (100)
)
peut créer des informations d'identification d'index pour cette table. L'instruction SQL est la suivante :
Code du programme
Créer des informations d'identification INDEX SUR les utilisateurs.
(
Nom d'utilisateur,
Mot de passe
)
La création d'un index est facultative et dépend de vous. Veuillez vous référer aux informations pertinentes pour connaître les avantages et les inconvénients de l'indexation.
Ensuite, nous ajoutons des données à cette base de données d'utilisateurs. Le nom du personnage est de votre choix, mais il est préférable d'utiliser un nom significatif, tel que
"Administrateur" (administrateur de niveau supérieur), "Manager" (administrateur), "Membre" (membre rejoint), "Utilisateur" (utilisateur ordinaire), etc. Par exemple :
Nom d'utilisateur|Mot de passe|Rôles
"willmove"|"pwd123"|"Administrateur,Utilisateur"
SQL
de "amuhouse
"
|
Insérer DANS les utilisateurs (nom d'utilisateur, mot de passe, rôles d'utilisateur) VALEURS ('willmove','45CB41B32DCFB917CCD8614F1536D6DA','Administrateur,Utilisateur')
ALLER
Insérer DANS les utilisateurs (nom d'utilisateur, mot de passe, rôles d'utilisateur) VALEURS ('amuhouse','45CB41B32DCFB917CCD8614F1536D6DA','User')
ALLER
Notez que les rôles sont sensibles à la casse car ils le sont dans le fichier Web.config. Nous créons maintenant plusieurs pages nécessaires pour implémenter ce mécanisme d'authentification de sécurité.
Le premier est la page de connexion de l'utilisateur Login.aspx
Si vous n'avez pas encore créé d'application Web, créez-en une maintenant. Bien entendu, vous pouvez également créer cette page dans une application web existante. Ici, je suppose qu'une application Web nommée RolebasedAuth a été créée (c'est-à-dire un projet dans Visual Studio .Net). J'ai mis ce Login.aspx dans son répertoire racine, accessible via http://localhost/RolebasedAuth/Login.aspx .
Peu importe où ce Login.aspx est placé, mais il doit être accessible au public.
Sous le chemin racine de l'application, nous créons deux sous-répertoires secrets, à savoir Admin et User.
Ensuite, nous créons un système de connexion par authentification par formulaire qui prend en charge l'authentification par rôle. Étant donné que Microsoft ne fournit pas de mécanisme de mise en œuvre simple, nous devons consacrer du temps à créer nous-mêmes le ticket d'authentification. Il doit stocker une petite quantité d'informations. Bien entendu, certains noms doivent être les mêmes que ceux configurés dans Web.config, sinon ASP.NET pensera que votre ticket d'authentification n'est pas valide et vous obligera à rediriger vers la page de connexion. Nous ajoutons deux contrôles TextBox à Login.aspx dans VS.NET et les nommons UserNameTextBox et PasswordTextBox. Nous ajoutons également un bouton et le nommons LoginButton. Cliquez dessus pour saisir le code d'arrière-plan. Ajoutez le code requis dans la méthode LoginButton_Click. comme suit:
code de programme
private void LoginButton_Click (expéditeur de l'objet, System.EventArgs e)
{
//Initialiser l'authentification par formulaire
// Notez qu'il se trouve dans l'espace de noms System.Web.Security
// Ajoutez donc using System.Web.Security; au début du code
FormsAuthentication.Initialize ();
// Créer des objets de commande de connexion à la base de données et d'opération de base de données
// Notez qu'il se trouve dans l'espace de noms System.Data.SqlClient
// Ajoutez donc using System.Data.SqlClient; au début du code
Connexion SQLConnection =
new SqlConnection("Data Source=sun-willmove;integrated security=SSPI;Initial Catalog=WebSolution;");
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = "Sélectionnez UserRoles FROM Users Where UserName=@username " +
"ET Mot de passe=@mot de passe ";
// Remplis chaque paramètre
cmd.Parameters.Add("@username", SqlDbType.NVarChar, 100).Value =
NomUtilisateurTextBox.Text ;
cmd.Parameters.Add("@password", SqlDbType.NVarChar, 150).Value =
FormsAuthentication.HashPasswordForStoringInConfigFile(
PasswordTextBox.Text, "md5"); // ou "sha1"
// Exécuter la commande d'opération de base de données
conn.Open();
Lecteur SqlDataReader = cmd.ExecuteReader();
si (lecteur.Read())
{
// Pour implémenter l'authentification, créez un nouveau ticket
Ticket FormsAuthenticationTicket = nouveau FormsAuthenticationTicket (
1, // Numéro de version du ticket
UserNameTextBox.Text, // Détenteur du ticket
DateTime.Now, //Heure pour attribuer les tickets
DateTime.Now.AddMinutes(30), //Heure d'expiration
vrai, // nécessite le cookie de l'utilisateur
reader.GetString(0), // Données utilisateur, voici en fait le rôle de l'utilisateur
FormsAuthentication.FormsCookiePath);//Chemin de cookie valide
//Utilisez la clé machine du code machine pour crypter les cookies pour une transmission sécurisée
hachage de chaîne = FormsAuthentication.Encrypt(ticket);
Cookie HttpCookie = nouveau HttpCookie (
FormsAuthentication.FormsCookieName, // Le nom du cookie d'authentification
hash); //Cookie crypté
//Définissez le délai d'expiration du cookie pour qu'il soit cohérent avec le délai d'expiration des tickets
if (ticket.IsPersistent) cookie.Expires = ticket.Expiration;
//Ajouter des cookies à la réponse à la demande de page
Response.Cookies.Add(cookie);
//Rediriger l'utilisateur vers la page précédemment demandée,
// Si aucune page n'a été demandée auparavant, rediriger vers la page d'accueil
chaîne returnUrl = Request.QueryString["ReturnUrl"];
if (returnUrl == null) returnUrl = "./";
// N'appelle pas la méthode FormsAuthentication.RedirectFromLoginPage.
// Parce qu'il remplacera le ticket (cookie) qui vient d'être ajouté
Réponse.Redirect(returnUrl);
}
autre
{
// Ne dites pas à l'utilisateur "Le mot de passe est erroné", cela équivaut à donner une chance à l'intrus.
// Parce qu'ils savent que le nom d'utilisateur qu'ils ont saisi existe
//
ErrorLabel.Text = "Le nom d'utilisateur ou le mot de passe est erroné, veuillez réessayer !";
ErrorLabel.Visible = vrai ;
}
lecteur.Close();
conn.Close();
}
Le code de la page aspx frontale est le suivant :
code de programme
<%@ Page Language="c#" Codebehind="Login.aspx.cs" AutoEventWireup="false" Inherits="RolebasedAuth.Login" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<TÊTE>
<title>Connexion</title>
<meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
<méta name="CODE_LANGUAGE" Content="C#">
<meta name="vs_defaultClientScript" content="JavaScript">
<meta name="vs_targetSchema" content=" http://schemas.microsoft.com/intellisense/ie5 ">
</HEAD>
<corps>
<form id="Form1" method="post" runat="server">
<P>
<asp:Label id="Label1" runat="server">Nom d'utilisateur :</asp:Label>
<asp:TextBox id="UserNameTextBox" runat="server"></asp:TextBox></P>
<P><FONT face="宋体"> </FONT>
<asp:Label id="Label2" runat="server">Mot de passe :</asp:Label>
<asp:TextBox id="PasswordTextBox" runat="server" TextMode="Password"></asp:TextBox></P>
<P>
<asp:Label id="ErrorLabel" runat="server" Visible="False"></asp:Label></P>
<P>
<asp:Button id="LoginButton" runat="server" Text="Connexion"></asp:Button></P>
</form>
</corps>
</HTML>
Vous remarquerez ce que nous avons fait avec le mot de passe ci-dessus : le hacher. Le cryptage par hachage est un algorithme unidirectionnel (irréversible) qui génère un tableau unique de caractères. Ainsi, changer la casse d'une seule lettre du mot de passe produira une colonne de hachage complètement différente. Nous stockons ces mots de passe cryptés dans la base de données, qui est plus sécurisée. Dans une application pratique, vous souhaiterez peut-être récupérer un mot de passe oublié pour un utilisateur. Mais le hachage est irréversible, vous ne pourrez donc pas récupérer le mot de passe d'origine. Mais vous pouvez changer le mot de passe de l'utilisateur et lui communiquer le mot de passe modifié. Si un site Web peut vous donner d’anciens mots de passe, alors vous devez penser clairement : vos données utilisateur ne sont pas en sécurité ! En fait, la plupart des sites Web nationaux stockent directement les mots de passe des utilisateurs dans la base de données sans cryptage. Si un pirate informatique réussit, ces comptes d’utilisateurs sont en danger !
Sans SSL, votre mot de passe est transmis en texte clair sur le réseau. Il peut être volé lors de la transmission. Le cryptage des mots de passe côté serveur garantit uniquement la sécurité du stockage des mots de passe. Des informations relatives à SSL sont disponibles sur http://www.versign.com ou http://www.thewte.com .
Si vous ne souhaitez pas stocker le mot de passe crypté dans la base de données, vous pouvez modifier le code ci-dessus en
FormsAuthentication.HashPasswordForStoringInConfigFile(PasswordTextBox.Text, "md5") peut être remplacé par PasswordTextBox.Text.
Ensuite, nous devons modifier le fichier Global.asax. Si votre application Web ne dispose pas de ce fichier, veuillez cliquer avec le bouton droit sur le projet d'application Web et sélectionner "Ajouter->Ajouter un nouvel élément...->Classe d'application globale". Dans Global.asax ou Global.asax.cs, recherchez la méthode (fonction) appelée Application_AuthenticationRequest. Confirmez d'abord que les espaces de noms System.Security.Principal et System.Web.Security ont été inclus ou utilisés, puis modifiez-le. Le code modifié :
code de programme
protected void Application_AuthenticateRequest (expéditeur d'objet, EventArgs e)
{
si (HttpContext.Current.User != null)
{
si (HttpContext.Current.User.Identity.IsAuthenticated)
{
si (HttpContext.Current.User.Identity est FormsIdentity)
{
Identifiant FormsIdentity =
(FormsIdentity)HttpContext.Current.User.Identity;
FormsAuthenticationTicket ticket = id.Ticket;
// Récupère les données utilisateur stockées dans le ticket, ce qui est en fait le rôle de l'utilisateur ici
chaîne userData = ticket.UserData ;
string[] rôles = userData.Split(',');
HttpContext.Current.User = new GenericPrincipal(id, rôles);
}
}
}
}
Le ticket d'authentification (nom d'utilisateur et mot de passe) n'est pas stocké dans le cadre du cookie, et il ne peut pas l'être puisque les utilisateurs peuvent modifier leurs cookies.
En fait, FormsAuthentication utilise votre clé machine (généralement dans machine.config) pour chiffrer le ticket (FormsAuthenticationTicket). Nous utilisons UserData pour stocker les rôles des utilisateurs et générer de nouvelles informations d'identification. Une fois l'identifiant créé, il est ajouté au contexte actuel (c'est-à-dire HttpContext) afin qu'il puisse être utilisé pour récupérer le rôle de l'utilisateur.
Ensuite, nous configurons le répertoire secret (c'est-à-dire le « répertoire de sécurité », un répertoire auquel seuls des utilisateurs spécifiques tels que les administrateurs ont l'autorisation d'accéder). Vérifiez d'abord s'il existe un fichier Web.config dans le répertoire racine de votre application Web. Sinon, créez-en un. Vous pouvez également créer un fichier Web.config dans votre sous-répertoire. Bien entendu, ce fichier Web.config est restreint (certains paramètres ne peuvent pas être définis).
Pour implémenter l'authentification de sécurité, recherchezle code du programme
sous le nœud <system.web> dans le fichier Web.config dans le répertoire racine de l'application Web.
<authentication mode="Windows" />, remplacez-le par
<authentication mode="Forms">
<nom du formulaire = "AMUHOUSE.ASPXAUTH"
loginUrl="Connexion.aspx"
protection="Tous"
chemin="./" />
</authentification>
<autorisation>
<autoriser les utilisateurs="*"/>
</authorization>
Dans le nom="AMUHOUSE.ASPXAUTH" ci-dessus, le nom AMUHOUSE.ASPXAUTH est arbitraire. Pour contrôler les autorisations des utilisateurs ou des groupes d'utilisateurs, nous pouvons avoir deux méthodes. L'une consiste à configurer le fichier Web.config dans le répertoire racine de l'application et l'autre consiste à créer un fichier Web.config indépendant dans le répertoire secret. (Ce dernier peut être meilleur.) Si c'est le premier, le Web.config doit contenir le contenu suivant (ou un contenu similaire) :
code de programme
<configuration>
<système.web>
<mode d'authentification="Formulaires">
<nom du formulaire = "AMUHOUSE.ASPXAUTH"
loginUrl="login.aspx"
protection="Tous"
chemin="/"/>
</authentification>
<autorisation>
<autoriser les utilisateurs="*"/>
</autorisation>
</system.web>
<chemin d'emplacement="./Admin">
<système.web>
<autorisation>
<!-- Attention ! L’ordre et la casse des lignes suivantes sont très importants ! -->
<allow role="Administrateur"/>
<refuser les utilisateurs="*"/>
</autorisation>
</system.web>
</emplacement>
<chemin d'emplacement="./Utilisateur">
<système.web>
<autorisation>
<!-- Attention ! L’ordre et la casse des lignes suivantes sont très importants ! -->
<allow role="Utilisateur"/>
<refuser les utilisateurs="*"/>
</autorisation>
</system.web>
</emplacement>
</configuration>
Afin de rendre les répertoires des applications Web indépendants auparavant les uns des autres et de faciliter leur renommage ou leur déplacement, vous pouvez choisir de configurer un fichier Web.config distinct dans chaque sous-répertoire de sécurité. Il lui suffit de configurer le nœud <authorization/>, comme suit :
code de programme
<configuration>
<système.web>
<autorisation>
<!-- Attention ! L’ordre et la casse des lignes suivantes sont très importants ! -->
<allow role="Administrateur"/>
<refuser les utilisateurs="*"/>
</autorisation>
</system.web>
</configuration>
Il convient de rappeler à nouveau que les rôles ci-dessus sont sensibles à la casse. Pour plus de commodité, vous pouvez également modifier ce qui précède pour :
<allow role="Administrateur,administrateur" />
Si vous souhaitez autoriser ou refuser l'accès à plusieurs rôles à ce répertoire, vous pouvez les séparer par des virgules, telles que :
<allow role="Administrateur,Membre,Utilisateur" />
<deny users="*" />
À ce stade, nous avons configuré un mécanisme d'authentification de sécurité basé sur les rôles pour le site Web. Vous pouvez d'abord compiler votre programme, puis essayer d'accéder à un répertoire secret, tel que http://localhost/RolebasedAuth/Admin , auquel moment vous serez redirigé vers la page de connexion de l'utilisateur. Si vous vous connectez avec succès et que votre rôle dispose des droits d'accès à ce répertoire, vous reviendrez dans ce répertoire. Il peut y avoir des utilisateurs (ou des intrus) essayant d'accéder au répertoire confidentiel. Nous pouvons utiliser une session pour stocker le nombre de fois que l'utilisateur s'est connecté. Si le nombre dépasse un certain nombre, l'utilisateur ne sera pas autorisé à se connecter, et "Le système a rejeté votre demande de connexion !" s'affichera.
Ci-dessous, nous expliquons comment faire en sorte que les contrôles Web affichent un contenu différent en fonction des rôles des utilisateurs.
Parfois, il est préférable d'afficher le contenu en fonction du rôle de l'utilisateur, car vous ne souhaitez probablement pas créer un tas de pages avec beaucoup de contenu en double pour autant de rôles différents (groupes d'utilisateurs). Sur un tel site, différents comptes d'utilisateurs peuvent coexister et les comptes d'utilisateurs payants peuvent accéder à du contenu payant supplémentaire. Un autre exemple est une page qui affichera un bouton « Entrer Administrateur » renvoyant à la page Administrateur si l'utilisateur actuel a le rôle « Administrateur ». Nous allons implémenter cette page maintenant.
La classe GenericPrincipal que nous avons utilisée ci-dessus implémente l'interface IPincipal. Cette interface a une méthode appelée IsInRole(), et son paramètre est une chaîne. Cette chaîne est le rôle utilisateur à vérifier. Si nous souhaitons afficher le contenu aux utilisateurs connectés dont le rôle est "Administrateur", nous pouvons ajouter le code suivant dans Page_Load :
Code du programme
if (User.IsInRole("Administrateur"))
AdminLink.Visible = true;
Le code complet de la page est le suivant (pour plus de simplicité, le code d'arrière-plan est également écrit dans la page aspx) :
code de programme
<html>
<tête>
<titre>Bienvenue ! </titre>
<script runat="serveur">
protected void Page_Load (expéditeur d'objet, EventArgs e)
{
if (User.IsInRole("Administrateur"))
AdminLink.Visible = vrai ;
autre
AdminLink.Visible = faux ;
}
</script>
</tête>
<corps>
<h2>Bienvenue ! </h2>
<p>Bienvenue à Amu House http://amuhouse.com/ ^_^</p>
<asp:HyperLink id="AdminLink" runat="server"
Text="Page d'accueil de l'administrateur" NavigateUrl="./Admin"/>
</corps>
</html>
De cette manière, le champ HyperLink lié à l'annuaire Admin ne sera affiché qu'aux utilisateurs dont le rôle est Administrateur. Vous pouvez également fournir aux utilisateurs non connectés un lien vers la page de connexion, tel que :
code de programme
protected void Page_Load (expéditeur de l'objet, System.EventArgs e)
{
if (User.IsInRole("Administrateur"))
{
AdminLink.Text = "Administrateur, veuillez entrer";
AdminLink.NavigateUrl="./Admin";
}
sinon if(User.IsInRole("Utilisateur"))
{
AdminLink.Text = "Utilisateurs enregistrés, veuillez saisir";
AdminLink.NavigateUrl="./Utilisateur"
;
autre
{
AdminLink.Text = "Veuillez vous connecter";
AdminLink.NavigateUrl="Login.aspx?ReturnUrl=" + Request.Path;
}
}
Ici, en définissant la variable QueryString appelée ReturnUrl, nous pouvons renvoyer l'utilisateur à la page actuelle après une connexion réussie.
résumé:
Cet article est utilisé pour vous aider à comprendre l'importance et le caractère pratique des mécanismes de sécurité basés sur les rôles, et utilise également ASP.NET pour implémenter des mécanismes de sécurité basés sur les rôles. Ce n'est pas un mécanisme difficile à mettre en œuvre, mais il peut nécessiter une certaine connaissance des informations d'identification des utilisateurs, de la manière d'authentifier les utilisateurs et des utilisateurs autorisés. Je serais très heureux si vous le trouviez utile. J'espère qu'il pourra vous guider dans la mise en œuvre de l'authentification de sécurité par formulaire basée sur les rôles dans votre site Web.
Ci-joint:
Exemple de code source de projet pour cet article :