Partager via


Attribution de rôles aux utilisateurs (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 créer deux pages ASP.NET pour vous aider à gérer les utilisateurs appartenant à quels rôles. La première page inclut des fonctionnalités permettant de voir les utilisateurs qui appartiennent à un rôle donné, les rôles auxquels appartient un utilisateur particulier et la possibilité d’attribuer ou de supprimer un utilisateur particulier d’un rôle particulier. Dans la deuxième page, nous allons augmenter le contrôle CreateUserWizard afin qu’il inclue une étape pour spécifier les rôles auxquels appartient l’utilisateur nouvellement créé. Cela est utile dans les scénarios où un administrateur est en mesure de créer de nouveaux comptes d’utilisateur.

Introduction

Le tutoriel précédent a examiné l’infrastructure Rôles et le SqlRoleProvider; nous avons vu comment utiliser la Roles classe pour créer, récupérer et supprimer des rôles. En plus de créer et de supprimer des rôles, nous devons être en mesure d’affecter ou de supprimer des utilisateurs d’un rôle. Malheureusement, ASP.NET n’est fourni avec aucun contrôle Web pour la gestion des utilisateurs appartenant à quels rôles. Au lieu de cela, nous devons créer nos propres pages ASP.NET pour gérer ces associations. La bonne nouvelle est que l’ajout et la suppression d’utilisateurs à des rôles sont assez faciles. La Roles classe contient un certain nombre de méthodes permettant d’ajouter un ou plusieurs utilisateurs à un ou plusieurs rôles.

Dans ce tutoriel, nous allons créer deux pages ASP.NET pour vous aider à gérer les utilisateurs appartenant à quels rôles. La première page inclut des fonctionnalités permettant de voir les utilisateurs qui appartiennent à un rôle donné, les rôles auxquels appartient un utilisateur particulier et la possibilité d’attribuer ou de supprimer un utilisateur particulier d’un rôle particulier. Dans la deuxième page, nous allons augmenter le contrôle CreateUserWizard afin qu’il inclue une étape pour spécifier les rôles auxquels appartient l’utilisateur nouvellement créé. Cela est utile dans les scénarios où un administrateur est en mesure de créer de nouveaux comptes d’utilisateur.

C’est parti !

Liste des utilisateurs appartenant à quels rôles

La première étape de ce didacticiel consiste à créer une page web à partir de laquelle les utilisateurs peuvent être affectés à des rôles. Avant de nous préoccuper de la façon d’affecter des utilisateurs à des rôles, nous allons d’abord nous concentrer sur la façon de déterminer quels utilisateurs appartiennent à quels rôles. Il existe deux façons d’afficher ces informations : « par rôle » ou « par utilisateur ». Nous pouvons autoriser le visiteur à sélectionner un rôle et à lui montrer tous les utilisateurs qui appartiennent au rôle (l’affichage « par rôle »), ou nous pouvons inviter le visiteur à sélectionner un utilisateur et à lui montrer les rôles attribués à cet utilisateur (l’affichage « par utilisateur »).

La vue « par rôle » est utile dans les cas où le visiteur souhaite connaître l’ensemble d’utilisateurs appartenant à un rôle particulier ; la vue « par utilisateur » est idéale lorsque le visiteur a besoin de connaître le ou les rôles d’un utilisateur particulier. Nous allons que notre page inclue à la fois les interfaces « par rôle » et « par utilisateur ».

Nous allons commencer par créer l’interface « par utilisateur ». Cette interface se compose d’une liste déroulante et d’une liste de cases à cocher. La liste déroulante est remplie avec l’ensemble d’utilisateurs dans le système ; les cases à cocher énumèrent les rôles. La sélection d’un utilisateur dans la liste déroulante case activée les rôles auxquels l’utilisateur appartient. La personne qui visite la page peut ensuite case activée ou décocher les cases pour ajouter ou supprimer l’utilisateur sélectionné des rôles correspondants.

Notes

L’utilisation d’une liste déroulante pour répertorier les comptes d’utilisateur n’est pas un choix idéal pour les sites web où il peut y avoir des centaines de comptes d’utilisateur. Une liste déroulante est conçue pour permettre à un utilisateur de choisir un élément dans une liste relativement courte d’options. Il devient rapidement difficile à mesure que le nombre d’éléments de liste augmente. Si vous créez un site web qui aura potentiellement un grand nombre de comptes d’utilisateur, vous pouvez envisager d’utiliser une autre interface utilisateur, telle qu’une interface paginable GridView ou une interface filtrable qui invite le visiteur à choisir une lettre, puis affiche uniquement les utilisateurs dont le nom d’utilisateur commence par la lettre sélectionnée.

Étape 1 : Création de l’interface utilisateur « Par utilisateur »

Ouvrez la UsersAndRoles.aspx page. En haut de la page, ajoutez un contrôle Label Web nommé ActionStatus et effacez sa Text propriété. Nous utiliserons cette étiquette pour fournir des commentaires sur les actions effectuées, en affichant des messages tels que « L’utilisateur Tito a été ajouté au rôle Administrateurs » ou « L’utilisateur Jisun a été supprimé du rôle Superviseurs ». Pour que ces messages se distinguent, définissez la propriété label CssClass sur « Important ».

<p align="center"> 

     <asp:Label ID="ActionStatus" runat="server" CssClass="Important"></asp:Label> 
</p>

Ensuite, ajoutez la définition de classe CSS suivante à la feuille de Styles.css style :

.Important 
{ 
     font-size: large; 
     color: Red; 
}

Cette définition CSS indique au navigateur d’afficher l’étiquette à l’aide d’une grande police rouge. La figure 1 montre cet effet via le Designer Visual Studio.

La propriété CssClass de l’étiquette génère une police rouge volumineuse

Figure 1 : La propriété de l’étiquette CssClass génère une grande police rouge (cliquer pour afficher l’image en taille réelle)

Ensuite, ajoutez un DropDownList à la page, définissez sa ID propriété sur UserListet définissez sa AutoPostBack propriété sur True. Nous allons utiliser cette liste déroulante pour répertorier tous les utilisateurs du système. Ce DropDownList sera lié à une collection d’objets MembershipUser. Étant donné que nous voulons que DropDownList affiche la propriété UserName de l’objet MembershipUser (et l’utilise comme valeur des éléments de liste), définissez les propriétés et DataValueField de DataTextField DropDownList sur « UserName ».

Sous dropDownList, ajoutez un répéteur nommé UsersRoleList. Ce répéteur répertorie tous les rôles dans le système sous la forme d’une série de cases à cocher. Définissez le répéteur à l’aide du ItemTemplate balisage déclaratif suivant :

<asp:Repeater ID="UsersRoleList" runat="server"> 
     <ItemTemplate> 
          <asp:CheckBox runat="server" ID="RoleCheckBox" AutoPostBack="true" 

               Text='<%# Container.DataItem %>' /> 
          <br /> 
     </ItemTemplate> 
</asp:Repeater>

Le ItemTemplate balisage inclut un seul contrôle Web CheckBox nommé RoleCheckBox. La propriété checkBox AutoPostBack a la valeur True et la Text propriété est liée à Container.DataItem. La raison pour laquelle la syntaxe de liaison de données est simplement Container.DataItem parce que l’infrastructure Roles retourne la liste des noms de rôles sous la forme d’un tableau de chaînes, et c’est ce tableau de chaînes que nous allons lier au répéteur. Une description détaillée de la raison pour laquelle cette syntaxe est utilisée pour afficher le contenu d’un tableau lié à un contrôle Web de données dépasse la portée de ce didacticiel. Pour plus d’informations sur cette question, consultez Liaison d’un tableau scalaire à un contrôle Web de données.

À ce stade, le balisage déclaratif de votre interface « par utilisateur » doit ressembler à ce qui suit :

<h3>Manage Roles By User</h3> 

<p> 
     <b>Select a User:</b> 
     <asp:DropDownList ID="UserList" runat="server" AutoPostBack="True" 
          DataTextField="UserName" DataValueField="UserName"> 

     </asp:DropDownList> 
</p> 
<p> 
     <asp:Repeater ID="UsersRoleList" runat="server"> 
          <ItemTemplate> 
               <asp:CheckBox runat="server" ID="RoleCheckBox" AutoPostBack="true" 

                    Text='<%# Container.DataItem %>' /> 
               <br /> 
          </ItemTemplate> 
     </asp:Repeater> 
</p>

Nous sommes maintenant prêts à écrire le code pour lier l’ensemble de comptes d’utilisateur au DropDownList et l’ensemble de rôles au répéteur. Dans la classe code-behind de la page, ajoutez une méthode nommée BindUsersToUserList et une autre nommée BindRolesList, à l’aide du code suivant :

private void BindUsersToUserList() 
{ 
     // Get all of the user accounts 
     MembershipUserCollection users = Membership.GetAllUsers(); 
     UserList.DataSource = users; 
     UserList.DataBind(); 
}
 
private void BindRolesToList() 
{ 
     // Get all of the roles 
     string[] roles = Roles.GetAllRoles(); 
     UsersRoleList.DataSource = roles; 
     UsersRoleList.DataBind(); 
}

La BindUsersToUserList méthode récupère tous les comptes d’utilisateur dans le système via la Membership.GetAllUsers méthode . Cette opération retourne un MembershipUserCollection objet, qui est une collection d’instancesMembershipUser. Cette collection est ensuite liée à DropDownList UserList . Les MembershipUser instances qui maquillagent la collection contiennent diverses propriétés, telles UserNameque , Email, CreationDateet IsOnline. Pour indiquer à DropDownList d’afficher la valeur de la UserName propriété, vérifiez que les UserList propriétés et DataValueField de DataTextField DropDownList ont été définies sur « UserName ».

Notes

La Membership.GetAllUsers méthode a deux surcharges : une qui n’accepte aucun paramètre d’entrée et retourne tous les utilisateurs, et une autre qui prend des valeurs entières pour l’index de page et la taille de page, et retourne uniquement le sous-ensemble spécifié des utilisateurs. Lorsque de grandes quantités de comptes d’utilisateur sont affichés dans un élément d’interface utilisateur paginable, la deuxième surcharge peut être utilisée pour parcourir plus efficacement les utilisateurs, car elle retourne uniquement le sous-ensemble précis des comptes d’utilisateur plutôt que tous d’entre eux.

La BindRolesToList méthode commence par appeler la méthode de GetAllRolesla Roles classe, qui retourne un tableau de chaînes contenant les rôles dans le système. Ce tableau de chaînes est ensuite lié au répéteur.

Enfin, nous devons appeler ces deux méthodes lorsque la page est chargée pour la première fois. Ajoutez le code suivant au gestionnaire d'événements Page_Load :

protected void Page_Load(object sender, EventArgs e) 
{ 
     if (!Page.IsPostBack) 
     { 
          // Bind the users and roles 
          BindUsersToUserList(); 
          BindRolesToList(); 
     } 
}

Une fois ce code en place, prenez un moment pour visiter la page via un navigateur ; votre écran doit ressembler à la figure 2. Tous les comptes d’utilisateur sont renseignés dans la liste déroulante et, en dessous, chaque rôle apparaît sous la forme d’une case à cocher. Étant donné que nous définissons les AutoPostBack propriétés de DropDownList et CheckBoxes sur True, la modification de l’utilisateur sélectionné ou la vérification ou la désactivation d’un rôle entraîne une publication. Toutefois, aucune action n’est effectuée, car nous n’avons pas encore écrit de code pour gérer ces actions. Nous aborderons ces tâches dans les deux sections suivantes.

La page affiche les utilisateurs et les rôles

Figure 2 : La page affiche les utilisateurs et les rôles (cliquer pour afficher l’image en taille réelle)

Vérification des rôles auxquels appartient l’utilisateur sélectionné

Lorsque la page est chargée pour la première fois, ou chaque fois que le visiteur sélectionne un nouvel utilisateur dans la liste déroulante, nous devons mettre à jour les UsersRoleListcases à cocher de sorte qu’une case à cocher de rôle donné soit cochée uniquement si l’utilisateur sélectionné appartient à ce rôle. Pour ce faire, créez une méthode nommée CheckRolesForSelectedUser avec le code suivant :

private void CheckRolesForSelectedUser() 
{ 
     // Determine what roles the selected user belongs to 
     string selectedUserName = UserList.SelectedValue; 
     string[] selectedUsersRoles = Roles.GetRolesForUser(selectedUserName); 

     // Loop through the Repeater's Items and check or uncheck the checkbox as needed 

     foreach (RepeaterItem ri in UsersRoleList.Items) 
     { 
          // Programmatically reference the CheckBox 
          CheckBox RoleCheckBox = ri.FindControl("RoleCheckBox") as CheckBox; 
          // See if RoleCheckBox.Text is in selectedUsersRoles 
          if (selectedUsersRoles.Contains<string>(RoleCheckBox.Text)) 
               RoleCheckBox.Checked = true; 
          else 
               RoleCheckBox.Checked = false; 
     } 
}

Le code ci-dessus commence par déterminer qui est l’utilisateur sélectionné. Il utilise ensuite la méthode de GetRolesForUser(userName) la classe Roles pour renvoyer l’ensemble de rôles de l’utilisateur spécifié en tant que tableau de chaînes. Ensuite, les éléments du répéteur sont énumérés et la case CheckBox de RoleCheckBox chaque élément est référencée par programmation. Le CheckBox est vérifié uniquement si le rôle auquel il correspond est contenu dans le tableau de selectedUsersRoles chaînes.

Notes

La selectedUserRoles.Contains<string>(...) syntaxe ne sera pas compilée si vous utilisez ASP.NET version 2.0. La Contains<string> méthode fait partie de la bibliothèque LINQ, qui n’est pas ASP.NET 3.5. Si vous utilisez toujours ASP.NET version 2.0, utilisez la méthode à la Array.IndexOf<string> place.

La CheckRolesForSelectedUser méthode doit être appelée dans deux cas : lorsque la page est chargée pour la première fois et chaque fois que l’index UserList sélectionné de DropDownList est modifié. Par conséquent, appelez cette méthode à partir du Page_Load gestionnaire d’événements (après les appels à BindUsersToUserList et BindRolesToList). Créez également un gestionnaire d’événements pour l’événement de SelectedIndexChanged DropDownList et appelez cette méthode à partir de là.

protected void Page_Load(object sender, EventArgs e) 
{ 
     if (!Page.IsPostBack) 
     { 

          // Bind the users and roles 
          BindUsersToUserList(); 
          BindRolesToList(); 
          // Check the selected user's roles 
          CheckRolesForSelectedUser(); 
     } 
} 

... 

protected void UserList_SelectedIndexChanged(object sender, EventArgs e) 
{ 
     CheckRolesForSelectedUser(); 
}

Une fois ce code en place, vous pouvez tester la page via le navigateur. Toutefois, étant donné que la UsersAndRoles.aspx page n’a pas actuellement la possibilité d’affecter des utilisateurs à des rôles, aucun utilisateur n’a de rôle. Nous allons créer l’interface permettant d’attribuer des utilisateurs à des rôles dans un instant, afin que vous puissiez soit prendre mon mot que ce code fonctionne et vérifier qu’il le fait plus tard, ou vous pouvez ajouter manuellement des utilisateurs à des rôles en insérant des enregistrements dans le aspnet_UsersInRoles tableau afin de tester cette fonctionnalité maintenant.

Attribution et suppression d’utilisateurs de rôles

Lorsque le visiteur vérifie ou désactive un contrôle CheckBox dans le UsersRoleList répéteur, nous devons ajouter ou supprimer l’utilisateur sélectionné du rôle correspondant. La propriété de AutoPostBack CheckBox est actuellement définie sur True, ce qui provoque une publication à chaque fois qu’une case CheckBox dans le répétiteur est cochée ou décochée. En bref, nous devons créer un gestionnaire d’événements pour l’événement CheckChanged CheckBox. Étant donné que checkBox se trouve dans un contrôle Repeater, nous devons ajouter manuellement la plomberie du gestionnaire d’événements. Commencez par ajouter le gestionnaire d’événements à la classe code-behind en tant protected que méthode, comme suit :

protected void RoleCheckBox_CheckChanged(object sender, EventArgs e) 
{ 

}

Nous allons revenir pour écrire le code de ce gestionnaire d’événements dans un instant. Mais commençons par terminer la gestion des événements de plomberie. À partir de la Case à cocher dans la propriété du ItemTemplaterépéteur , ajoutez OnCheckedChanged="RoleCheckBox_CheckChanged". Cette syntaxe relie le RoleCheckBox_CheckChanged gestionnaire d’événements à l’événement RoleCheckBoxde CheckedChanged .

<asp:CheckBox runat="server" ID="RoleCheckBox" 
     AutoPostBack="true" 
     Text='<%# Container.DataItem %>' 
     OnCheckedChanged="RoleCheckBox_CheckChanged" />

Notre dernière tâche consiste à terminer le gestionnaire d’événements RoleCheckBox_CheckChanged . Nous devons commencer par référencer le contrôle CheckBox qui a déclenché l’événement, car cette instance CheckBox nous indique quel rôle a été vérifié ou décoché via ses Text propriétés et Checked . À l’aide de ces informations avec le userName de l’utilisateur sélectionné, nous ajoutons ou supprimons l’utilisateur du rôle par le biais de la classe ou RemoveUserFromRolede AddUserToRole la Roles méthode .

protected void RoleCheckBox_CheckChanged(object sender, EventArgs e) 
{ 
     // Reference the CheckBox that raised this event 
     CheckBox RoleCheckBox = sender as CheckBox; 

     // Get the currently selected user and role 
     string selectedUserName = UserList.SelectedValue; 

     string roleName = RoleCheckBox.Text; 

     // Determine if we need to add or remove the user from this role 
     if (RoleCheckBox.Checked) 
     { 
          // Add the user to the role 
          Roles.AddUserToRole(selectedUserName, roleName); 
          // Display a status message 
          ActionStatus.Text = string.Format("User {0} was added to role {1}.", selectedUserName, roleName); 
     } 
     else 
     { 
          // Remove the user from the role 
          Roles.RemoveUserFromRole(selectedUserName, roleName); 
          // Display a status message 
          ActionStatus.Text = string.Format("User {0} was removed from role {1}.", selectedUserName, roleName); 

     } 
}

Le code ci-dessus commence par référencer par programmation la CheckBox qui a déclenché l’événement, qui est disponible via le sender paramètre d’entrée. Si la case CheckBox est cochée, l’utilisateur sélectionné est ajouté au rôle spécifié; sinon, il est supprimé du rôle. Dans les deux cas, l’étiquette ActionStatus affiche un message résumant l’action que vous venez d’effectuer.

Prenez un moment pour tester cette page via un navigateur. Sélectionnez L’utilisateur Tito, puis ajoutez Tito aux rôles Administrateurs et Superviseurs.

Tito a été ajouté aux rôles Administrateurs et Superviseurs

Figure 3 : Tito a été ajouté aux rôles Administrateurs et Superviseurs (Cliquez pour afficher l’image en taille réelle)

Ensuite, sélectionnez user Bruce dans la liste déroulante. Il existe une publication et les CheckBox du répétiteur sont mis à jour via le CheckRolesForSelectedUser. Étant donné que Bruce n’appartient à aucun rôle, les deux cases à cocher sont décochées. Ensuite, ajoutez Bruce au rôle Superviseurs.

Bruce a été ajouté au rôle de superviseur

Figure 4 : Bruce a été ajouté au rôle Superviseurs (cliquez pour afficher l’image en taille réelle)

Pour vérifier davantage les fonctionnalités de la CheckRolesForSelectedUser méthode, sélectionnez un utilisateur autre que Tito ou Bruce. Notez que les cases à cocher sont automatiquement décochées, indiquant qu’elles n’appartiennent à aucun rôle. Revenez à Tito. Les cases Administrateurs et Superviseurs doivent être cochées.

Étape 2 : Génération de l’interface utilisateur « Par rôles »

À ce stade, nous avons terminé l’interface « by users » et sommes prêts à commencer à aborder l’interface « by roles ». L’interface « par rôles » invite l’utilisateur à sélectionner un rôle dans une liste déroulante, puis affiche l’ensemble des utilisateurs qui appartiennent à ce rôle dans un GridView.

Ajoutez un autre contrôle DropDownList à la UsersAndRoles.aspx page. Placez celui-ci sous le contrôle Repeater, nommez-le RoleListet définissez sa AutoPostBack propriété sur True. En dessous, ajoutez un GridView et nommez-le RolesUserList. Ce GridView répertorie les utilisateurs qui appartiennent au rôle sélectionné. Définissez la propriété de AutoGenerateColumns GridView sur False, ajoutez un TemplateField à la collection de Columns la grille et définissez sa HeaderText propriété sur « Users ». Définissez l’objet TemplateField afin qu’il ItemTemplate affiche la valeur de l’expression Container.DataItem de liaison de données dans la Text propriété d’un label nommé UserNameLabel.

Après avoir ajouté et configuré GridView, le balisage déclaratif de votre interface « par rôle » doit ressembler à ce qui suit :

<h3>Manage Users By Role</h3> 
<p> 
     <b>Select a Role:</b> 

     <asp:DropDownList ID="RoleList" runat="server" AutoPostBack="true"></asp:DropDownList> 
</p> 
<p>      <asp:GridView ID="RolesUserList" runat="server" AutoGenerateColumns="false" 

          EmptyDataText="No users belong to this role."> 
          <Columns> 
               <asp:TemplateField HeaderText="Users"> 
                    <ItemTemplate> 
                         <asp:Label runat="server" id="UserNameLabel" 
                              Text='<%# Container.DataItem %>'></asp:Label> 

                    </ItemTemplate> 
               </asp:TemplateField> 
          </Columns> 
     </asp:GridView> </p>

Nous devons remplir le RoleList DropDownList avec l’ensemble des rôles dans le système. Pour ce faire, mettez à jour la BindRolesToList méthode afin que soit lié le tableau de chaînes retourné par la Roles.GetAllRoles méthode au RolesList DropDownList (ainsi qu’au UsersRoleList répéteur).

private void BindRolesToList() 
{ 
     // Get all of the roles 

     string[] roles = Roles.GetAllRoles(); 
     UsersRoleList.DataSource = roles; 
     UsersRoleList.DataBind(); 

     RoleList.DataSource = roles; 
     RoleList.DataBind(); 
}

Les deux dernières lignes de la BindRolesToList méthode ont été ajoutées pour lier l’ensemble des rôles au RoleList contrôle DropDownList. La figure 5 montre le résultat final lorsqu’il est consulté via un navigateur: une liste déroulante remplie avec les rôles du système.

Les rôles sont affichés dans la liste déroulante RoleList

Figure 5 : Les rôles sont affichés dans la RoleList liste déroulante (cliquez pour afficher l’image en taille réelle)

Affichage des utilisateurs qui appartiennent au rôle sélectionné

Lorsque la page est chargée pour la première fois ou qu’un nouveau rôle est sélectionné dans la RoleList liste DropDownList, nous devons afficher la liste des utilisateurs qui appartiennent à ce rôle dans GridView. Créez une méthode nommée DisplayUsersBelongingToRole à l’aide du code suivant :

private void DisplayUsersBelongingToRole() 
{ 
     // Get the selected role 
     string selectedRoleName = RoleList.SelectedValue; 

     // Get the list of usernames that belong to the role 
     string[] usersBelongingToRole = Roles.GetUsersInRole(selectedRoleName); 

     // Bind the list of users to the GridView 
     RolesUserList.DataSource = usersBelongingToRole; 
     RolesUserList.DataBind(); 
}

Cette méthode commence par obtenir le rôle sélectionné à partir du RoleList DropDownList. Il utilise ensuite la Roles.GetUsersInRole(roleName) méthode pour récupérer un tableau de chaînes des UserNames des utilisateurs qui appartiennent à ce rôle. Ce tableau est ensuite lié à GridView RolesUserList .

Cette méthode doit être appelée dans deux circonstances : lorsque la page est initialement chargée et lorsque le rôle sélectionné dans le RoleList DropDownList change. Par conséquent, mettez à jour le Page_Load gestionnaire d’événements afin que cette méthode soit appelée après l’appel à CheckRolesForSelectedUser. Ensuite, créez un gestionnaire d’événements pour l’événement RoleListde SelectedIndexChanged , puis appelez cette méthode à partir de là également.

protected void Page_Load(object sender, EventArgs e) 
{ 
     if (!Page.IsPostBack) 
     { 
          // Bind the users and roles 
          BindUsersToUserList(); 
          BindRolesToList(); 

          // Check the selected user's roles 
          CheckRolesForSelectedUser(); 

          // Display those users belonging to the currently selected role 
          DisplayUsersBelongingToRole(); 
     } 
} 

... 

protected void RoleList_SelectedIndexChanged(object sender, EventArgs e) 
{ 
     DisplayUsersBelongingToRole(); 
}

Une fois ce code en place, GridView RolesUserList doit afficher les utilisateurs qui appartiennent au rôle sélectionné. Comme le montre la figure 6, le rôle superviseur se compose de deux membres : Bruce et Tito.

GridView répertorie les utilisateurs qui appartiennent au rôle sélectionné

Figure 6 : GridView répertorie les utilisateurs qui appartiennent au rôle sélectionné (cliquez pour afficher l’image en taille réelle)

Suppression des utilisateurs du rôle sélectionné

Nous allons augmenter le RolesUserList GridView afin qu’il inclue une colonne de boutons « Supprimer ». Cliquez sur le bouton « Supprimer » pour un utilisateur particulier pour le supprimer de ce rôle.

Commencez par ajouter un champ de bouton Supprimer à GridView. Faites apparaître ce champ comme étant le plus à gauche et remplacez sa DeleteText propriété de « Delete » (valeur par défaut) par « Remove ».

Capture d’écran montrant comment ajouter le bouton « Supprimer » dans la fenêtre Champs.

Figure 7 : Ajouter le bouton « Supprimer » à GridView (cliquer pour afficher l’image en taille réelle)

Lorsque l’utilisateur clique sur le bouton « Supprimer », une publication de publication s’ensuit et l’événement gridView RowDeleting est déclenché. Nous devons créer un gestionnaire d’événements pour cet événement et écrire du code qui supprime l’utilisateur du rôle sélectionné. Créez le gestionnaire d’événements, puis ajoutez le code suivant :

protected void RolesUserList_RowDeleting(object sender, GridViewDeleteEventArgs e) 
{ 
     // Get the selected role 
     string selectedRoleName = RoleList.SelectedValue; 

     // Reference the UserNameLabel 
     Label UserNameLabel = RolesUserList.Rows[e.RowIndex].FindControl("UserNameLabel") as Label; 

     // Remove the user from the role 
     Roles.RemoveUserFromRole(UserNameLabel.Text, selectedRoleName); 

     // Refresh the GridView 
     DisplayUsersBelongingToRole(); 

     // Display a status message 
     ActionStatus.Text = string.Format("User {0} was removed from role {1}.", UserNameLabel.Text, selectedRoleName); 
}

Le code commence par déterminer le nom du rôle sélectionné. Il référence ensuite par programmation le UserNameLabel contrôle à partir de la ligne sur laquelle on a cliqué sur le bouton « Supprimer » afin de déterminer le nom d’utilisateur de l’utilisateur à supprimer. L’utilisateur est ensuite supprimé du rôle via un appel à la Roles.RemoveUserFromRole méthode . GridView RolesUserList est ensuite actualisé et un message s’affiche via le ActionStatus contrôle Label.

Notes

Le bouton « Supprimer » ne nécessite aucune confirmation de la part de l’utilisateur avant de le supprimer du rôle. Je vous invite à ajouter un niveau de confirmation de l’utilisateur. L’un des moyens les plus simples de confirmer une action consiste à utiliser une boîte de dialogue de confirmation côté client. Pour plus d’informations sur cette technique, consultez Ajout de Client-Side confirmation lors de la suppression.

La figure 8 montre la page après que l’utilisateur Tito a été supprimé du groupe Superviseurs.

Hélas, Tito n’est plus un superviseur

Figure 8 : Hélas, Tito n’est plus un superviseur (cliquer pour afficher l’image en taille réelle)

Ajout de nouveaux utilisateurs au rôle sélectionné

En plus de supprimer des utilisateurs du rôle sélectionné, le visiteur de cette page doit également être en mesure d’ajouter un utilisateur au rôle sélectionné. La meilleure interface pour ajouter un utilisateur au rôle sélectionné dépend du nombre de comptes d’utilisateur que vous prévoyez d’avoir. Si votre site web n’héberge que quelques dizaines de comptes d’utilisateur ou moins, vous pouvez utiliser un DropDownList ici. S’il peut y avoir des milliers de comptes d’utilisateur, vous souhaitez inclure une interface utilisateur qui permet au visiteur de parcourir les comptes, de rechercher un compte particulier ou de filtrer les comptes d’utilisateur d’une autre manière.

Pour cette page, nous allons utiliser une interface très simple qui fonctionne quel que soit le nombre de comptes d’utilisateur dans le système. À savoir, nous allons utiliser un TextBox, invitant le visiteur à taper le nom d’utilisateur de l’utilisateur qu’il souhaite ajouter au rôle sélectionné. S’il n’existe aucun utilisateur portant ce nom, ou si l’utilisateur est déjà membre du rôle, nous allons afficher un message dans ActionStatus Label. Mais si l’utilisateur existe et n’est pas membre du rôle, nous allons l’ajouter au rôle et actualiser la grille.

Ajoutez une zone de texte et un bouton sous GridView. Définissez les TextBox sur IDUserNameToAddToRole et définissez les propriétés et Text du ID bouton sur AddUserToRoleButton et « Ajouter un utilisateur au rôle », respectivement.

<p> 
     <b>UserName:</b> 
     <asp:TextBox ID="UserNameToAddToRole" runat="server"></asp:TextBox> 
     <br /> 
     <asp:Button ID="AddUserToRoleButton" runat="server" Text="Add User to Role" /> 

</p>

Ensuite, créez un gestionnaire d’événements Click pour et AddUserToRoleButton ajoutez le code suivant :

protected void AddUserToRoleButton_Click(object sender, EventArgs e) 
{ 
     // Get the selected role and username 

     string selectedRoleName = RoleList.SelectedValue; 
     string userNameToAddToRole = UserNameToAddToRole.Text; 

     // Make sure that a value was entered 
     if (userNameToAddToRole.Trim().Length == 0) 
     { 
          ActionStatus.Text = "You must enter a username in the textbox."; 
          return; 
     } 

     // Make sure that the user exists in the system 
     MembershipUser userInfo = Membership.GetUser(userNameToAddToRole); 
     if (userInfo == null) 
     { 
          ActionStatus.Text = string.Format("The user {0} does not exist in the system.", userNameToAddToRole); 

          return; 
     } 

     // Make sure that the user doesn't already belong to this role 
     if (Roles.IsUserInRole(userNameToAddToRole, selectedRoleName)) 
     { 
          ActionStatus.Text = string.Format("User {0} already is a member of role {1}.", userNameToAddToRole, selectedRoleName); 
          return; 
     } 

     // If we reach here, we need to add the user to the role 
     Roles.AddUserToRole(userNameToAddToRole, selectedRoleName); 

     // Clear out the TextBox 
     UserNameToAddToRole.Text = string.Empty; 

     // Refresh the GridView 
     DisplayUsersBelongingToRole(); 

     // Display a status message 

     ActionStatus.Text = string.Format("User {0} was added to role {1}.", userNameToAddToRole, selectedRoleName); }

La majorité du code dans le gestionnaire d’événements Click effectue différentes vérifications de validation. Cela garantit que le visiteur a fourni un nom d’utilisateur dans textBox UserNameToAddToRole , que l’utilisateur existe dans le système et qu’il n’appartient pas déjà au rôle sélectionné. Si l’une de ces vérifications échoue, un message approprié s’affiche dans ActionStatus et le gestionnaire d’événements est quitté. Si toutes les vérifications réussissent, l’utilisateur est ajouté au rôle via la Roles.AddUserToRole méthode . Par la suite, la propriété textbox Text est effacée, le GridView est actualisé et l’étiquette ActionStatus affiche un message indiquant que l’utilisateur spécifié a été correctement ajouté au rôle sélectionné.

Notes

Pour nous assurer que l’utilisateur spécifié n’appartient pas déjà au rôle sélectionné, nous utilisons la Roles.IsUserInRole(userName, roleName) méthode, qui retourne une valeur booléenne indiquant si userName est membre de roleName. Nous utiliserons à nouveau cette méthode dans le tutoriel suivant lorsque nous examinerons l’autorisation basée sur les rôles.

Accédez à la page via un navigateur et sélectionnez le rôle Superviseurs dans la RoleList liste déroulante. Essayez d’entrer un nom d’utilisateur non valide : vous devez voir un message expliquant que l’utilisateur n’existe pas dans le système.

Vous ne pouvez pas ajouter un utilisateur inexistant à un rôle

Figure 9 : Vous ne pouvez pas ajouter un utilisateur inexistant à un rôle (cliquer pour afficher l’image en taille réelle)

Essayez maintenant d’ajouter un utilisateur valide. Continuez et rajoutez Tito au rôle Superviseurs.

Tito est encore une fois superviseur!

Figure 10 : Tito est à nouveau superviseur! (Cliquez pour afficher l’image en taille réelle)

Étape 3 : Mise à jour croisée des interfaces « Par utilisateur » et « Par rôle »

La UsersAndRoles.aspx page propose deux interfaces distinctes pour la gestion des utilisateurs et des rôles. Actuellement, ces deux interfaces agissent indépendamment l’une de l’autre de sorte qu’il est possible qu’une modification apportée dans une interface ne soit pas reflétée immédiatement dans l’autre. Par exemple, imaginez que le visiteur de la page sélectionne le rôle Superviseurs dans dropDownList RoleList , qui répertorie Bruce et Tito comme membres. Ensuite, le visiteur sélectionne Tito dans la UserList Liste déroulante, qui coche les cases Administrateurs et Superviseurs dans le UsersRoleList Répéteur. Si le visiteur décochait ensuite le rôle Superviseur du Répéteur, Tito est supprimé du rôle Superviseurs, mais cette modification n’est pas reflétée dans l’interface « par rôle ». GridView montre toujours Tito comme membre du rôle Superviseurs.

Pour résoudre ce problème, nous devons actualiser gridView chaque fois qu’un rôle est coché ou décoché à partir du UsersRoleList répéteur. De même, nous devons actualiser le répéteur chaque fois qu’un utilisateur est supprimé ou ajouté à un rôle à partir de l’interface « par rôle ».

Le répéteur dans l’interface « par utilisateur » est actualisé en appelant la CheckRolesForSelectedUser méthode . L’interface « par rôle » peut être modifiée dans le RolesUserList gestionnaire d’événements RowDeleting GridView et le AddUserToRoleButton gestionnaire d’événements de Click Button. Par conséquent, nous devons appeler la CheckRolesForSelectedUser méthode de chacune de ces méthodes.

protected void RolesUserList_RowDeleting(object sender, GridViewDeleteEventArgs e) 
{ 
     ... Code removed for brevity ... 

     // Refresh the "by user" interface 
     CheckRolesForSelectedUser(); 
} 

protected void AddUserToRoleButton_Click(object sender, EventArgs e) 
{ 
     ... Code removed for brevity ... 


     // Refresh the "by user" interface 
     CheckRolesForSelectedUser(); 
}

De même, le GridView de l’interface « par rôle » est actualisé en appelant la DisplayUsersBelongingToRole méthode et l’interface « par utilisateur » est modifiée via le RoleCheckBox_CheckChanged gestionnaire d’événements. Par conséquent, nous devons appeler la DisplayUsersBelongingToRole méthode à partir de ce gestionnaire d’événements.

protected void RoleCheckBox_CheckChanged(object sender, EventArgs e) 
{ 
     ... Code removed for brevity... 

     // Refresh the "by role" interface 
     DisplayUsersBelongingToRole(); 
}

Avec ces modifications mineures du code, les interfaces « par utilisateur » et « par rôle » sont désormais correctement mises à jour croisées. Pour vérifier cela, accédez à la page via un navigateur et sélectionnez Tito et Superviseurs dans les UserList listes déroulantes et RoleList , respectivement. Notez que lorsque vous décochez le rôle Superviseurs pour Tito du répéteur dans l’interface « par utilisateur », Tito est automatiquement supprimé de GridView dans l’interface « par rôle ». L’ajout de Tito au rôle Superviseurs à partir de l’interface « par rôle » réactive automatiquement la case Superviseurs dans l’interface « par utilisateur ».

Étape 4 : Personnalisation de l’étape CreateUserWizard pour inclure une étape « Spécifier des rôles »

Dans le tutoriel Création de comptes d’utilisateur, nous avons vu comment utiliser le contrôle Web CreateUserWizard pour fournir une interface permettant de créer un compte d’utilisateur. Le contrôle CreateUserWizard peut être utilisé de l’une des deux manières suivantes :

  • Comme un moyen pour les visiteurs de créer leur propre compte d’utilisateur sur le site, et
  • Comme moyen pour les administrateurs de créer de nouveaux comptes

Dans le premier cas d’usage, un visiteur se présente sur le site et remplit le CreateUserWizard, en entrant ses informations afin de s’inscrire sur le site. Dans le deuxième cas, un administrateur crée un compte pour une autre personne.

Lorsqu’un compte est créé par un administrateur pour une autre personne, il peut être utile de permettre à l’administrateur de spécifier les rôles auxquels appartient le nouveau compte d’utilisateur. Dans le tutoriel Stockaged’informations supplémentaires sur l’utilisateur, nous avons vu comment personnaliser CreateUserWizard en ajoutant des informations supplémentairesWizardSteps. Voyons comment ajouter une étape supplémentaire à CreateUserWizard afin de spécifier les rôles du nouvel utilisateur.

Ouvrez la CreateUserWizardWithRoles.aspx page et ajoutez un contrôle CreateUserWizard nommé RegisterUserWithRoles. Définissez la propriété du ContinueDestinationPageUrl contrôle sur « ~/Default.aspx ». Étant donné que l’idée ici est qu’un administrateur utilisera ce contrôle CreateUserWizard pour créer de nouveaux comptes d’utilisateur, définissez la propriété du LoginCreatedUser contrôle sur False. Cette LoginCreatedUser propriété spécifie si le visiteur est connecté automatiquement en tant qu’utilisateur qui vient de créer et si la valeur par défaut est True. Nous l’avons défini sur False, car lorsqu’un administrateur crée un compte, nous voulons le maintenir connecté en tant que lui-même.

Ensuite, sélectionnez « Ajouter/Supprimer WizardSteps... » à partir de l’option CreateUserWizard’s Smart Tag et ajoutez un nouveau WizardStep, en définissant sa ID sur SpecifyRolesStep. Déplacez le SpecifyRolesStep WizardStep afin qu’il arrive après l’étape « Inscription à votre nouveau compte », mais avant l’étape « Terminer ». Définissez la WizardSteppropriété de Title sur « Spécifier des rôles », sa StepType propriété sur Stepet sa AllowReturn propriété sur False.

Capture d’écran montrant les propriétés Spécifier les rôles sélectionnées dans la fenêtre Assistant Éditeur de collection d’étapes.

Figure 11 : Ajouter le « Spécifier des rôles » WizardStep à CreateUserWizard (Cliquez pour afficher l’image en taille réelle)

Après cette modification, le balisage déclaratif de votre CreateUserWizard doit ressembler à ce qui suit :

<asp:CreateUserWizard ID="RegisterUserWithRoles" runat="server" 
     ContinueDestinationPageUrl="~/Default.aspx" LoginCreatedUser="False"> 

     <WizardSteps> 
          <asp:CreateUserWizardStep ID="CreateUserWizardStep1" runat="server"> 
          </asp:CreateUserWizardStep> 
          <asp:WizardStep ID="SpecifyRolesStep" runat="server" StepType="Step" 

               Title="Specify Roles" AllowReturn="False"> 
          </asp:WizardStep> 
          <asp:CompleteWizardStep ID="CompleteWizardStep1" runat="server"> 
          </asp:CompleteWizardStep> 
     </WizardSteps> 

</asp:CreateUserWizard>

Dans « Spécifier des rôles », WizardStepajoutez une checkBoxList nommée RoleList. Cette checkBoxList répertorie les rôles disponibles, ce qui permet à la personne qui visite la page de case activée les rôles auxquels appartient l’utilisateur nouvellement créé.

Il nous reste deux tâches de codage : d’abord, nous devons remplir la RoleList CheckBoxList avec les rôles dans le système ; deuxièmement, nous devons ajouter l’utilisateur créé aux rôles sélectionnés lorsque l’utilisateur passe de l’étape « Spécifier les rôles » à l’étape « Terminer ». Nous pouvons accomplir la première tâche du gestionnaire d’événements Page_Load . Le code suivant fait référence par programmation à CheckBox RoleList lors de la première visite à la page et y lie les rôles dans le système.

protected void Page_Load(object sender, EventArgs e) 
{ 
     if (!Page.IsPostBack) 
     { 
          // Reference the SpecifyRolesStep WizardStep 
          WizardStep SpecifyRolesStep = RegisterUserWithRoles.FindControl("SpecifyRolesStep") as WizardStep; 

          // Reference the RoleList CheckBoxList 
          CheckBoxList RoleList = SpecifyRolesStep.FindControl("RoleList") as CheckBoxList; 

          // Bind the set of roles to RoleList 
          RoleList.DataSource = Roles.GetAllRoles(); 
          RoleList.DataBind(); 
     } 
}

Le code ci-dessus doit être familier. Dans le tutoriel Stockaged’informations utilisateur supplémentaires, nous avons utilisé deux FindControl instructions pour référencer un contrôle Web à partir d’un contrôle personnalisé WizardStep. Et le code qui lie les rôles à CheckBoxList a été extrait plus haut dans ce tutoriel.

Pour effectuer la deuxième tâche de programmation, nous devons savoir quand l’étape « Spécifier les rôles » est terminée. Rappelez-vous que CreateUserWizard a un ActiveStepChanged événement, qui se déclenche chaque fois que le visiteur navigue d’une étape à l’autre. Ici, nous pouvons déterminer si l’utilisateur a atteint l’étape « Terminé » ; si c’est le cas, nous devons ajouter l’utilisateur aux rôles sélectionnés.

Créez un gestionnaire d’événements pour l’événement ActiveStepChanged et ajoutez le code suivant :

protected void RegisterUserWithRoles_ActiveStepChanged(object sender, EventArgs e) 
{ 
     // Have we JUST reached the Complete step? 
     if (RegisterUserWithRoles.ActiveStep.Title == "Complete") 
     { 
          // Reference the SpecifyRolesStep WizardStep 
          WizardStep SpecifyRolesStep = RegisterUserWithRoles.FindControl("SpecifyRolesStep") as WizardStep; 

          // Reference the RoleList CheckBoxList 
          CheckBoxList RoleList = SpecifyRolesStep.FindControl("RoleList") as CheckBoxList; 

          // Add the checked roles to the just-added user 
          foreach (ListItem li in RoleList.Items) 

          { 
               if (li.Selected) 
                    Roles.AddUserToRole(RegisterUserWithRoles.UserName, li.Text); 
          } 
     } 
}

Si l’utilisateur vient d’atteindre l’étape « Terminé », le gestionnaire d’événements énumère les éléments du RoleList CheckBoxList et l’utilisateur qui vient d’être créé est affecté aux rôles sélectionnés.

Visitez cette page via un navigateur. La première étape de CreateUserWizard est l’étape standard « S’inscrire à votre nouveau compte », qui invite à entrer le nom d’utilisateur, le mot de passe, l’e-mail et d’autres informations clés du nouvel utilisateur. Entrez les informations pour créer un utilisateur nommé Wanda.

Créer un utilisateur nommé Wanda

Figure 12 : Créer un utilisateur nommé Wanda (cliquer pour afficher l’image en taille réelle)

Cliquez sur le bouton « Créer un utilisateur ». CreateUserWizard appelle en interne la Membership.CreateUser méthode, crée le nouveau compte d’utilisateur, puis passe à l’étape suivante, « Spécifier des rôles ». Ici, les rôles système sont répertoriés. Cochez la case Superviseurs, puis cliquez sur Suivant.

Faire de Wanda un membre du rôle Superviseurs

Figure 13 : Faire de Wanda un membre du rôle Superviseurs (cliquer pour afficher l’image en taille réelle)

Cliquer sur Suivant entraîne une publication et met à jour l’étape ActiveStep « Terminé ». Dans le ActiveStepChanged gestionnaire d’événements, le compte d’utilisateur créé récemment est affecté au rôle Superviseurs. Pour vérifier cela, revenez à la UsersAndRoles.aspx page et sélectionnez Superviseurs dans la RoleList liste déroulante. Comme le montre la figure 14, les superviseurs sont désormais composés de trois utilisateurs : Bruce, Tito et Wanda.

Bruce, Tito et Wanda sont tous superviseurs

Figure 14 : Bruce, Tito et Wanda sont tous des superviseurs (cliquer pour afficher l’image en taille réelle)

Résumé

L’infrastructure Rôles offre des méthodes pour récupérer des informations sur les rôles d’un utilisateur particulier et des méthodes permettant de déterminer quels utilisateurs appartiennent à un rôle spécifié. En outre, il existe un certain nombre de méthodes permettant d’ajouter et de supprimer un ou plusieurs utilisateurs à un ou plusieurs rôles. Dans ce tutoriel, nous nous sommes concentrés uniquement sur deux de ces méthodes : AddUserToRole et RemoveUserFromRole. Il existe d’autres variantes conçues pour ajouter plusieurs utilisateurs à un seul rôle et pour attribuer plusieurs rôles à un seul utilisateur.

Ce tutoriel comprenait également une présentation de l’extension du contrôle CreateUserWizard pour y inclure un WizardStep pour spécifier les rôles de l’utilisateur nouvellement créé. Une telle étape pourrait aider un administrateur à simplifier le processus de création de comptes d’utilisateur pour de nouveaux utilisateurs.

À ce stade, nous avons vu comment créer et supprimer des rôles et comment ajouter et supprimer des utilisateurs de rôles. Mais nous n’avons pas encore examiné l’application de l’autorisation basée sur les rôles. Dans le tutoriel suivant , nous allons examiner la définition des règles d’autorisation d’URL sur une base de rôle par rôle, ainsi que la façon de limiter les fonctionnalités au niveau de la page en fonction des rôles d’utilisateur actuellement connectés.

Bonne programmation!

En savoir plus

Pour plus d’informations sur les sujets abordés dans ce tutoriel, reportez-vous aux ressources suivantes :

À 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 Heures. Scott peut être contacté à mitchell@4guysfromrolla.com ou via son blog à l’adresse http://ScottOnWriting.NET.

Un merci spécial à...

Cette série de tutoriels a été examinée par de nombreux réviseurs utiles. La réviseur principale de ce tutoriel était Teresa Murphy. Vous souhaitez consulter mes prochains articles MSDN ? Si c’est le cas, déposez-moi une ligne à mitchell@4GuysFromRolla.com