Partager via


Autorisation basée sur le rôle (VB)

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

Ce didacticiel commence par une présentation de la façon dont l’infrastructure Rôles associe les rôles d’un utilisateur à son contexte de sécurité. Il examine ensuite comment appliquer des règles d’autorisation d’URL basées sur le rôle. Nous examinerons ensuite l’utilisation de moyens déclaratifs et programmatiques pour modifier les données affichées et les fonctionnalités offertes par une page ASP.NET.

Introduction

Dans le didacticiel Autorisation basée sur l’utilisateur, nous avons vu comment utiliser l’autorisation d’URL pour spécifier les utilisateurs qui peuvent visiter un ensemble particulier de pages. Avec juste un peu de balisage dans Web.config, nous pourrions demander à ASP.NET d’autoriser uniquement les utilisateurs authentifiés à visiter une page. Ou nous pourrions dicter que seuls les utilisateurs Tito et Bob étaient autorisés, ou indiquer que tous les utilisateurs authentifiés à l’exception de Sam étaient autorisés.

En plus de l’autorisation d’URL, nous avons également examiné les techniques déclaratives et programmatiques pour contrôler les données affichées et les fonctionnalités offertes par une page en fonction de la visite de l’utilisateur. En particulier, nous avons créé une page qui répertorie le contenu du répertoire actif. Tout le monde pouvait visiter cette page, mais seuls les utilisateurs authentifiés pouvaient afficher le contenu des fichiers et seul Tito pouvait supprimer les fichiers.

L’application de règles d’autorisation utilisateur par utilisateur peut devenir un cauchemar de comptabilité. Une approche plus gérable consiste à utiliser l’autorisation basée sur les rôles. La bonne nouvelle est que les outils à notre disposition pour appliquer des règles d’autorisation fonctionnent aussi bien avec les rôles que pour les comptes d’utilisateur. Les règles d’autorisation d’URL peuvent spécifier des rôles plutôt que des utilisateurs. Le contrôle LoginView, qui affiche des sorties différentes pour les utilisateurs authentifiés et anonymes, peut être configuré pour afficher du contenu différent en fonction des rôles de l’utilisateur connecté. Et l’API Rôles inclut des méthodes permettant de déterminer les rôles de l’utilisateur connecté.

Ce didacticiel commence par une présentation de la façon dont l’infrastructure Rôles associe les rôles d’un utilisateur à son contexte de sécurité. Il examine ensuite comment appliquer des règles d’autorisation d’URL basées sur le rôle. Nous examinerons ensuite l’utilisation de moyens déclaratifs et programmatiques pour modifier les données affichées et les fonctionnalités offertes par une page ASP.NET. C’est parti !

Présentation de la façon dont les rôles sont associés au contexte de sécurité d’un utilisateur

Chaque fois qu’une requête entre dans le pipeline ASP.NET, elle est associée à un contexte de sécurité, qui comprend des informations identifiant le demandeur. Lors de l’utilisation de l’authentification par formulaire, un ticket d’authentification est utilisé comme jeton d’identité. Comme nous l’avons vu dans le tutoriel Vue d’ensemble de l’authentification par formulaire, le FormsAuthenticationModule est chargé de déterminer l’identité du demandeur, ce qu’il fait pendant l’événementAuthenticateRequest.

Si un ticket d’authentification valide et non expiré est trouvé, le FormsAuthenticationModule décode pour vérifier l’identité du demandeur. Il crée un GenericPrincipal objet et l’affecte à l’objet HttpContext.User . L’objectif d’un principal, comme GenericPrincipal, est d’identifier le nom de l’utilisateur authentifié et les rôles auxquels il appartient. Cet objectif est évident par le fait que tous les objets principaux ont une Identity propriété et une IsInRole(roleName) méthode. Toutefois, le FormsAuthenticationModule, n’est pas intéressé par l’enregistrement des informations de rôle et l’objet GenericPrincipal qu’il crée ne spécifie aucun rôle.

Si l’infrastructure Rôles est activée, le RoleManagerModule module HTTP suit et FormsAuthenticationModule identifie les rôles de l’utilisateur authentifié pendant l’événementPostAuthenticateRequest, qui se déclenche après l’événementAuthenticateRequest. Si la requête provient d’un utilisateur authentifié, le RoleManagerModule remplace l’objet GenericPrincipal créé par et le FormsAuthenticationModule remplace par un RolePrincipal objet. La RolePrincipal classe utilise l’API Rôles pour déterminer les rôles auxquels l’utilisateur appartient.

La figure 1 illustre le flux de travail de pipeline ASP.NET lors de l’utilisation de l’authentification par formulaire et de l’infrastructure Rôles. S’exécute FormsAuthenticationModule d’abord, identifie l’utilisateur via son ticket d’authentification et crée un nouvel GenericPrincipal objet. Ensuite, les RoleManagerModule étapes et remplacent l’objet GenericPrincipal par un RolePrincipal objet.

Si un utilisateur anonyme visite le site, ni le FormsAuthenticationModule ne RoleManagerModule crée d’objet principal.

Événements de pipeline ASP.NET pour un utilisateur authentifié lors de l’utilisation de l’authentification par formulaire et de l’infrastructure rôles

Figure 1 : Événements de pipeline ASP.NET pour un utilisateur authentifié lors de l’utilisation de l’authentification par formulaire et de l’infrastructure rôles (cliquer pour afficher l’image en taille réelle)

La RolePrincipal méthode de l’objet IsInRole(roleName) appelle Roles.GetRolesForUser pour obtenir les rôles de l’utilisateur afin de déterminer si l’utilisateur est membre de roleName. Lors de l’utilisation de SqlRoleProvider, cela entraîne une requête vers la base de données du magasin de rôles. Lors de l’utilisation de règles d’autorisation d’URL basées sur le rôle, la RolePrincipalméthode de IsInRole est appelée à chaque requête adressée à une page protégée par les règles d’autorisation d’URL basées sur le rôle. Au lieu d’avoir à rechercher les informations de rôle dans la base de données à chaque demande, l’infrastructure Roles inclut une option permettant de mettre en cache les rôles de l’utilisateur dans un cookie.

Si l’infrastructure Rôles est configurée pour mettre en cache les rôles de l’utilisateur dans un cookie, le RoleManagerModule crée le cookie pendant l’événement du EndRequestpipeline ASP.NET. Ce cookie est utilisé dans les requêtes suivantes dans le PostAuthenticateRequest, qui correspond au moment de la création de l’objet RolePrincipal . Si le cookie est valide et n’a pas expiré, les données contenues dans le cookie sont analysées et utilisées pour remplir les rôles de l’utilisateur, ce qui évite RolePrincipal d’avoir à passer un appel à la Roles classe pour déterminer les rôles de l’utilisateur. La figure 2 illustre ce flux de travail.

Les informations de rôle de l’utilisateur peuvent être stockées dans un cookie pour améliorer les performances

Figure 2 : Les informations de rôle de l’utilisateur peuvent être stockées dans un cookie pour améliorer les performances (cliquez pour afficher l’image en taille réelle)

Par défaut, le mécanisme de cookie de cache de rôle est désactivé. Il peut être activé via le <roleManager>balisage de configuration dans Web.config. Nous avons discuté de l’utilisation de l’élément<roleManager> pour spécifier des fournisseurs de rôles dans le didacticiel Création et gestion des rôles. Vous devez donc déjà avoir cet élément dans le fichier de Web.config votre application. Les paramètres de cookie de cache de rôle sont spécifiés en tant qu’attributs de l’élément <roleManager>; et sont résumés dans le tableau 1.

Notes

Les paramètres de configuration répertoriés dans le tableau 1 spécifient les propriétés du cookie de cache de rôle résultant. Pour plus d’informations sur les cookies, leur fonctionnement et leurs différentes propriétés, consultez ce tutoriel Cookies.

Propriété Description
cacheRolesInCookie Valeur booléenne qui indique si la mise en cache des cookies est utilisée. La valeur par défaut est false.
cookieName Nom du cookie de cache de rôle. La valeur par défaut est . ASPXROLES ».
cookiePath Chemin d’accès du cookie de nom des rôles. L’attribut path permet à un développeur de limiter l’étendue d’un cookie à une hiérarchie d’annuaires particulière. La valeur par défaut est « / », ce qui indique au navigateur d’envoyer le cookie de ticket d’authentification à toute demande adressée au domaine.
cookieProtection Indique les techniques utilisées pour protéger le cookie de cache de rôle. Les valeurs autorisées sont : All (valeur par défaut) ; Encryption; None; et Validation.md)

| cookieRequireSSL | Valeur booléenne qui indique si une connexion SSL est nécessaire pour transmettre le cookie d’authentification. La valeur par défaut est false cookieSlidingExpiration false createPersistentCookieis set totrue. | | cookieTimeout | Specifies the time, in minutes, after which the authentication ticket cookie expires. The default value is30. This value is only pertinent when createPersistentCookieis set totrue. | | createPersistentCookie | A Boolean value that specifies whether the role cache cookie is a session cookie or persistent cookie. Iffalse(the default), a session cookie is used, which is deleted when the browser is closed. Iftrue, a persistent cookie is used; it expires cookieTimeoutnumber of minutes after it has been created or after the previous visit, depending on the value ofcookieSlidingExpiration. | | domaine de domaineattribute, setting it to "yourdomain.com". | | | Specifies the cookie's domain value. The default value is an empty string, which causes the browser to use the domain from which it was issued (such as www.yourdomain.com). In this case, the cookie will <strong>not</strong> be sent when making requests to subdomains, such as admin.yourdomain.com. If you want the cookie to be passed to all subdomains you need to customize themaxCachedResults | Specifies the maximum number of role names that are cached in the cookie. The default is 25. TheRoleManagerModuledoes not create a cookie for users that belong to more thanmaxCachedResultsroles. Consequently, theRolePrincipalobject'sIsInRolemethod will use theRolesclass to determine the user's roles. The reasonmaxCachedResultsexists is because many user agents do not permit cookies larger than 4,096 bytes. So this cap is meant to reduce the likelihood of exceeding this size limitation. If you have extremely long role names, you may want to consider specifying a smaller. This value is only pertinent when | A Boolean value that indicates whether the cookie's timeout is reset each time the user visits the site during a single session. The default value is. | | valeur de maxCachedResults ; à l’inverse, si vous avez des noms de rôles extrêmement courts, vous pouvez probablement augmenter cette valeur. |

Tableau 1 : Options de configuration des cookies de cache de rôle

Nous allons configurer notre application pour utiliser des cookies de cache de rôle non persistants. Pour ce faire, mettez à jour l’élément <roleManager> dans Web.config pour inclure les attributs liés aux cookies suivants :

<roleManager enabled="true" 
          defaultProvider="SecurityTutorialsSqlRoleProvider"
          cacheRolesInCookie="true"
          createPersistentCookie="false"
          cookieProtection="All">

     <providers>
     ...
     </providers>
</roleManager>

J’ai mis à jour l’élément <roleManager>; en ajoutant trois attributs : cacheRolesInCookie, createPersistentCookieet cookieProtection. En définissant cacheRolesInCookie sur true, RoleManagerModule le met désormais automatiquement en cache les rôles de l’utilisateur dans un cookie plutôt que d’avoir à rechercher les informations de rôle de l’utilisateur sur chaque requête. J’ai explicitement défini les createPersistentCookie attributs false et cookieProtection sur et All, respectivement. Techniquement, je n’ai pas eu besoin de spécifier des valeurs pour ces attributs, car je viens de les affecter à leurs valeurs par défaut, mais je les ai placées ici pour indiquer clairement que je n’utilise pas de cookies persistants et que le cookie est à la fois chiffré et validé.

C’est tout ! Désormais, l’infrastructure Rôles met en cache les rôles des utilisateurs dans les cookies. Si le navigateur de l’utilisateur ne prend pas en charge les cookies, ou si leurs cookies sont supprimés ou perdus, d’une manière ou d’une autre, ce n’est pas grave : l’objet RolePrincipal utilise simplement la Roles classe dans le cas où aucun cookie (ou un cookie non valide ou expiré) n’est disponible.

Notes

Le groupe Modèles & Pratiques de Microsoft décourage l’utilisation de cookies de cache de rôle persistants. Étant donné que la possession du cookie de cache de rôle est suffisante pour prouver l’appartenance au rôle, si un pirate peut d’une manière ou d’une autre accéder au cookie d’un utilisateur valide, il peut emprunter l’identité de cet utilisateur. La probabilité que cela se produise augmente si le cookie est persistant dans le navigateur de l’utilisateur. Pour plus d’informations sur cette recommandation de sécurité, ainsi que sur d’autres problèmes de sécurité, reportez-vous à la Liste des questions de sécurité pour ASP.NET 2.0.

Étape 1 : Définition des règles d’autorisation d’URL Role-Based

Comme indiqué dans le didacticiel Sur l’autorisation basée sur l’utilisateur, l’autorisation d’URL offre un moyen de restreindre l’accès à un ensemble de pages sur une base utilisateur par utilisateur ou rôle par rôle. Les règles d’autorisation d’URL sont décrites dans Web.config à l’aide de l’élément<authorization> avec <allow> les éléments enfants et <deny> . Outre les règles d’autorisation liées à l’utilisateur décrites dans les didacticiels précédents, chaque <allow> élément enfant <deny> peut également inclure :

  • Un rôle particulier
  • Liste de rôles délimitées par des virgules

Par exemple, les règles d’autorisation d’URL accordent l’accès à ces utilisateurs dans les rôles Administrateurs et Superviseurs, mais refusent l’accès à tous les autres :

<authorization>

     <allow roles="Administrators, Supervisors" />
     <deny users="*" />
</authorization>

L’élément <allow> dans le balisage ci-dessus indique que les rôles Administrateurs et Superviseurs sont autorisés ; l’élément ; l’élément <deny>; indique que tous les utilisateurs sont refusés.

Nous allons configurer notre application afin que les ManageRoles.aspxpages , UsersAndRoles.aspxet CreateUserWizardWithRoles.aspx soient accessibles uniquement aux utilisateurs ayant le rôle Administrateurs, tandis que la RoleBasedAuthorization.aspx page reste accessible à tous les visiteurs.

Pour ce faire, commencez par ajouter un Web.config fichier au Roles dossier .

Ajouter un fichier Web.config au répertoire Roles

Figure 3 : Ajouter un Web.config fichier au Roles répertoire (cliquer pour afficher l’image en taille réelle)

Ensuite, ajoutez le balisage de configuration suivant à Web.config:

<?xml version="1.0"?>

<configuration>
     <system.web>
          <authorization>
               <allow roles="Administrators" />
               <deny users="*"/>
          </authorization>

     </system.web>

     <!-- Allow all users to visit RoleBasedAuthorization.aspx -->
     <location path="RoleBasedAuthorization.aspx">
          <system.web>
               <authorization>
                    <allow users="*" />

               </authorization>
          </system.web>
     </location>
</configuration>

L’élément <authorization> de la <system.web> section indique que seuls les utilisateurs du rôle Administrateurs peuvent accéder aux ressources ASP.NET dans le Roles répertoire. L’élément <location> définit un autre ensemble de règles d’autorisation d’URL pour la RoleBasedAuthorization.aspx page, permettant à tous les utilisateurs de visiter la page.

Après avoir enregistré vos modifications dans Web.config, connectez-vous en tant qu’utilisateur qui n’est pas dans le rôle Administrateurs, puis essayez de visiter l’une des pages protégées. Le UrlAuthorizationModule détecte que vous n’avez pas l’autorisation de visiter la ressource demandée ; par conséquent, le FormsAuthenticationModule vous redirige vers la page de connexion. La page de connexion vous redirige ensuite vers la page (voir la UnauthorizedAccess.aspx figure 4). Cette redirection finale de la page de connexion vers UnauthorizedAccess.aspx se produit en raison du code que nous avons ajouté à la page de connexion à l’étape 2 du didacticiel Sur l’autorisation basée sur l’utilisateur. En particulier, la page de connexion redirige automatiquement tout utilisateur authentifié vers UnauthorizedAccess.aspx si la chaîne de requête contient un ReturnUrl paramètre, car ce paramètre indique que l’utilisateur est arrivé à la page de connexion après avoir tenté d’afficher une page qu’il n’était pas autorisé à afficher.

Seuls les utilisateurs ayant le rôle Administrateurs peuvent afficher les pages protégées

Figure 4 : Seuls les utilisateurs du rôle Administrateurs peuvent afficher les pages protégées (Cliquer pour afficher l’image en taille réelle)

Déconnectez-vous, puis connectez-vous en tant qu’utilisateur qui est dans le rôle Administrateurs. Vous devriez maintenant être en mesure d’afficher les trois pages protégées.

Tito peut visiter la page UsersAndRoles.aspx parce qu’il est dans le rôle Administrateurs

Figure 5 : Tito peut visiter la UsersAndRoles.aspx page parce qu’il est dans le rôle Administrateurs (cliquez pour afficher l’image en taille réelle)

Notes

Lorsque vous spécifiez des règles d’autorisation d’URL (pour des rôles ou des utilisateurs), il est important de garder à l’esprit que les règles sont analysées une par une, de haut en bas. Dès qu’une correspondance est trouvée, l’accès est accordé ou refusé à l’utilisateur, selon que la correspondance a été trouvée dans un <allow> élément ou <deny> . Si aucune correspondance n’est trouvée, l’accès est accordé à l’utilisateur. Par conséquent, si vous souhaitez restreindre l’accès à un ou plusieurs comptes d’utilisateur, il est impératif d’utiliser un <deny> élément comme dernier élément dans la configuration d’autorisation d’URL. Si vos règles d’autorisation d’URL n’incluent pas de<deny>, tous les utilisateurs se verront accorder l’accès. Pour une discussion plus approfondie sur la façon dont les règles d’autorisation d’URL sont analysées, reportez-vous à la section « A Look at How the UrlAuthorizationModule Use the Authorization Rules to Grant or Deny Access » du didacticiel Sur l’autorisation basée sur l’utilisateur.

Étape 2 : Limitation des fonctionnalités basées sur les rôles d’utilisateur actuellement connectés

L’autorisation d’URL permet de spécifier facilement des règles d’autorisation grossières qui indiquent quelles identités sont autorisées et lesquelles ne peuvent pas afficher une page particulière (ou toutes les pages d’un dossier et ses sous-dossiers). Toutefois, dans certains cas, nous pouvons autoriser tous les utilisateurs à visiter une page, mais limiter les fonctionnalités de la page en fonction des rôles de l’utilisateur qui visite. Cela peut impliquer d’afficher ou de masquer des données basées sur le rôle de l’utilisateur, ou d’offrir des fonctionnalités supplémentaires aux utilisateurs qui appartiennent à un rôle particulier.

Ces règles d’autorisation basées sur les rôles précises peuvent être implémentées de manière déclarative ou par programmation (ou par le biais d’une combinaison des deux). Dans la section suivante, nous verrons comment implémenter l’autorisation déclarative fine via le contrôle LoginView. Ensuite, nous allons explorer les techniques de programmation. Toutefois, avant de pouvoir envisager d’appliquer des règles d’autorisation précises, nous devons d’abord créer une page dont les fonctionnalités dépendent du rôle de l’utilisateur qui la visite.

Créons une page qui répertorie tous les comptes d’utilisateur dans le système dans un GridView. GridView inclut le nom d’utilisateur, l’adresse e-mail, la date de dernière connexion et les commentaires relatifs à l’utilisateur. En plus d’afficher les informations de chaque utilisateur, GridView inclut des fonctionnalités de modification et de suppression. Nous allons initialement créer cette page avec les fonctionnalités de modification et de suppression disponibles pour tous les utilisateurs. Dans les sections « Utilisation du contrôle LoginView » et « Fonctionnalité de limitation par programmation », nous allons voir comment activer ou désactiver ces fonctionnalités en fonction du rôle de l’utilisateur qui visite.

Notes

La page ASP.NET que nous allons créer utilise un contrôle GridView pour afficher les comptes d’utilisateur. Étant donné que cette série de tutoriels se concentre sur l’authentification par formulaire, l’autorisation, les comptes d’utilisateur et les rôles, je ne veux pas passer trop de temps à discuter du fonctionnement interne du contrôle GridView. Bien que ce tutoriel fournisse des instructions pas à pas spécifiques pour configurer cette page, il ne se penche pas sur les raisons pour lesquelles certains choix ont été effectués ou sur l’effet de propriétés particulières sur la sortie rendue. Pour un examen approfondi du contrôle GridView, case activée ma série de didacticiels Sur l’utilisation des données dans ASP.NET 2.0.

Commencez par ouvrir la RoleBasedAuthorization.aspx page dans le Roles dossier . Faites glisser un GridView de la page sur le Designer et définissez sa ID sur UserGrid. Dans un instant, nous allons écrire du code qui appelle le Membership.GetAllUsers et lie l’objet résultant MembershipUserCollection à GridView. contient MembershipUserCollection un MembershipUser objet pour chaque compte d’utilisateur dans le système ; MembershipUser les objets ont des propriétés telles que UserName,EmailLastLoginDate et ainsi de suite.

Avant d’écrire le code qui lie les comptes d’utilisateur à la grille, commençons par définir les champs de GridView. À partir de la balise active gridView, cliquez sur le lien « Modifier les colonnes » pour lancer la boîte de dialogue Champs (voir la figure 6). À partir de là, décochez la case « Générer automatiquement des champs » dans le coin inférieur gauche. Étant donné que nous voulons que ce GridView inclue des fonctionnalités d’édition et de suppression, ajoutez un Champ de commande et définissez ses ShowEditButton propriétés et sur ShowDeleteButton True. Ensuite, ajoutez quatre champs pour afficher les UserNamepropriétés , Email, LastLoginDateet Comment . Utilisez un objet BoundField pour les deux propriétés en lecture seule (UserName et LastLoginDate) et templateFields pour les deux champs modifiables (Email et Comment).

Le premier Objet BoundField affiche la UserName propriété ; définissez ses HeaderText propriétés et DataField sur « UserName ». Ce champ n’étant pas modifiable, définissez sa ReadOnly propriété sur True. Configurez BoundField LastLoginDate en définissant sur HeaderText « Dernière connexion » et sur DataField « LastLoginDate ». Nous allons mettre en forme la sortie de ce champ boundField de sorte que seule la date soit affichée (au lieu de la date et de l’heure). Pour ce faire, définissez la propriété de HtmlEncode ce champ boundfield sur False et sa DataFormatString propriété sur «{0:d} ». Définissez également la propriété sur ReadOnly True.

Définissez les HeaderText propriétés des deux Champs de modèles sur « Email » et « Commentaire ».

Les champs de GridView peuvent être configurés via la boîte de dialogue Champs

Figure 6 : Les champs de GridView peuvent être configurés via la boîte de dialogue Champs (cliquez pour afficher l’image en taille réelle)

Nous devons maintenant définir les ItemTemplate et EditItemTemplate pour les champs de modèles « Email » et « Comment ». Ajoutez un contrôle Label Web à chacun des ItemTemplates et liez leurs Text propriétés aux Email propriétés et Comment , respectivement.

Pour le champ TemplateField « Email », ajoutez un TextBox nommé Email à son EditItemTemplate et liez sa Text propriété à la propriété à l’aide de la Email liaison de données bidirectionnel. Ajoutez un RequiredFieldValidator et un RegularExpressionValidator à pour EditItemTemplate vous assurer qu’un visiteur qui modifie la propriété Email a entré une adresse e-mail valide. Pour le TemplateField « Comment », ajoutez un TextBox multiligne nommé Comment à son EditItemTemplate. Définissez les propriétés et Rows de Columns TextBox sur 40 et 4, respectivement, puis liez sa Text propriété à la propriété à l’aide de la Comment liaison de données bidirectionnel.

Après avoir configuré ces TemplateFields, leur balisage déclaratif doit ressembler à ce qui suit :

<asp:TemplateField HeaderText="Email">
     <ItemTemplate>
          <asp:Label runat="server" ID="Label1" Text='<%# Eval("Email")%>'></asp:Label>

     </ItemTemplate>
     <EditItemTemplate>
          <asp:TextBox runat="server" ID="Email" Text='<%# Bind("Email")%>'></asp:TextBox>

          <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" 
               ControlToValidate="Email" Display="Dynamic"
               ErrorMessage="You must provide an email address."
               SetFocusOnError="True">*</asp:RequiredFieldValidator>

          <asp:RegularExpressionValidator ID="RegularExpressionValidator1" runat="server"
               ControlToValidate="Email" Display="Dynamic"
               ErrorMessage="The email address you have entered is not valid. Please fix 
               this and try again."
               SetFocusOnError="True"

               ValidationExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*">*
          </asp:RegularExpressionValidator>
     </EditItemTemplate>
</asp:TemplateField>

<asp:TemplateField HeaderText="Comment">
     <ItemTemplate>
          <asp:Label runat="server" ID="Label2" Text='<%# Eval("Comment")%>'></asp:Label>

     </ItemTemplate>
     <EditItemTemplate>
          <asp:TextBox runat="server" ID="Comment" TextMode="MultiLine"
               Columns="40" Rows="4" Text='<%# Bind("Comment")%>'>

          </asp:TextBox>
     </EditItemTemplate>
</asp:TemplateField>

Lors de la modification ou de la suppression d’un compte d’utilisateur, nous devons connaître la valeur de propriété de UserName cet utilisateur. Définissez la propriété de DataKeyNames GridView sur « UserName » afin que ces informations soient disponibles via la collection gridView DataKeys .

Enfin, ajoutez un contrôle ValidationSummary à la page et définissez sa ShowMessageBox propriété sur True et sa ShowSummary propriété sur False. Avec ces paramètres, validationSummary affiche une alerte côté client si l’utilisateur tente de modifier un compte d’utilisateur avec une adresse e-mail manquante ou non valide.

<asp:ValidationSummary ID="ValidationSummary1"
               runat="server"
               ShowMessageBox="True"
               ShowSummary="False" />

Nous avons maintenant terminé le balisage déclaratif de cette page. Notre tâche suivante consiste à lier l’ensemble de comptes d’utilisateur à GridView. Ajoutez une méthode nommée BindUserGrid à la classe code-behind de la RoleBasedAuthorization.aspx page qui lie le MembershipUserCollection retourné par Membership.GetAllUsers à GridView UserGrid . Appelez cette méthode à partir du Page_Load gestionnaire d’événements lors de la première visite de page.

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
     If Not Page.IsPostBack Then
          BindUserGrid()
     End If
End Sub

Private Sub BindUserGrid()
     Dim allUsers As MembershipUserCollection = Membership.GetAllUsers()
     UserGrid.DataSource = allUsers
     UserGrid.DataBind()
End Sub

Une fois ce code en place, visitez la page via un navigateur. Comme le montre la figure 7, vous devez voir une liste GridView des informations sur chaque compte d’utilisateur dans le système.

UserGrid GridView répertorie des informations sur chaque utilisateur dans le système

Figure 7 : GridView UserGrid répertorie des informations sur chaque utilisateur dans le système (cliquez pour afficher l’image en taille réelle)

Notes

GridView UserGrid répertorie tous les utilisateurs d’une interface non paginée. Cette interface de grille simple ne convient pas aux scénarios où il y a plusieurs dizaines d’utilisateurs ou plus. Une option consiste à configurer GridView pour activer la pagination. 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. 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 . Si vous avez des milliers de comptes d’utilisateur, vous pouvez envisager une interface basée sur un filtre, qui affiche uniquement les utilisateurs dont le nom d’utilisateur commence par un caractère sélectionné, pour instance. La Membership.FindUsersByName méthode est idéale pour créer une interface utilisateur basée sur des filtres. Nous allons examiner la création d’une telle interface dans un prochain tutoriel.

Le contrôle GridView offre une prise en charge intégrée de la modification et de la suppression lorsque le contrôle est lié à un contrôle de source de données correctement configuré, tel que SqlDataSource ou ObjectDataSource. Le UserGrid GridView, cependant, a ses données liées par programmation ; par conséquent, nous devons écrire du code pour effectuer ces deux tâches. En particulier, nous devrons créer des gestionnaires d’événements pour les événements GridView RowEditing, RowCancelingEdit, RowUpdatinget RowDeleting qui sont déclenchés lorsqu’un visiteur clique sur les boutons Modifier, Annuler, Mettre à jour ou Supprimer de GridView.

Commencez par créer les gestionnaires d’événements pour les événements , RowCancelingEditet RowUpdating de RowEditingGridView, puis ajoutez le code suivant :

Protected Sub UserGrid_RowEditing(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewEditEventArgs) Handles UserGrid.RowEditing
     ' Set the grid's EditIndex and rebind the data

     UserGrid.EditIndex = e.NewEditIndex
     BindUserGrid()
End Sub

Protected Sub UserGrid_RowCancelingEdit(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCancelEditEventArgs) Handles UserGrid.RowCancelingEdit
     ' Revert the grid's EditIndex to -1 and rebind the data
     UserGrid.EditIndex = -1
     BindUserGrid()
End Sub
    
Protected Sub UserGrid_RowUpdating(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewUpdateEventArgs) Handles UserGrid.RowUpdating
     ' Exit if the page is not valid
     If Not Page.IsValid Then
          Exit Sub
     End If

     ' Determine the username of the user we are editing
     Dim UserName As String = UserGrid.DataKeys(e.RowIndex).Value.ToString()

     ' Read in the entered information and update the user
     Dim EmailTextBox As TextBox = CType(UserGrid.Rows(e.RowIndex).FindControl("Email"),TextBox)
     Dim CommentTextBox As TextBox= CType(UserGrid.Rows(e.RowIndex).FindControl("Comment"),TextBox)

     ' Return information about the user
     Dim UserInfo As MembershipUser = Membership.GetUser(UserName)

     ' Update the User account information
     UserInfo.Email = EmailTextBox.Text.Trim()
     UserInfo.Comment = CommentTextBox.Text.Trim()

     Membership.UpdateUser(UserInfo)

     ' Revert the grid's EditIndex to -1 and rebind the data
     UserGrid.EditIndex = -1
     BindUserGrid()
End Sub

Les RowEditing gestionnaires d’événements et RowCancelingEdit définissent simplement la propriété gridView EditIndex , puis relient la liste des comptes d’utilisateur à la grille. Les choses intéressantes se produisent dans le RowUpdating gestionnaire d’événements. Ce gestionnaire d’événements commence par s’assurer que les données sont valides, puis récupère la UserName valeur du compte d’utilisateur modifié dans la DataKeys collection. Comment Les Email et TextBox dans les deux TemplateFields sont ensuite référencés EditItemTemplate par programme. Leurs Text propriétés contiennent l’adresse e-mail et le commentaire modifiés.

Pour mettre à jour un compte d’utilisateur via l’API d’appartenance, nous devons d’abord obtenir les informations de l’utilisateur, ce que nous faisons via un appel à Membership.GetUser(userName). Les propriétés et Comment de l’objet Email retournés MembershipUser sont ensuite mises à jour avec les valeurs entrées dans les deux TextBox à partir de l’interface de modification. Enfin, ces modifications sont enregistrées avec un appel à Membership.UpdateUser. Le RowUpdating gestionnaire d’événements se termine en rétablissant GridView à son interface de pré-édition.

Ensuite, créez le RowDeleting gestionnaire d’événements RowDeleting, puis ajoutez le code suivant :

Protected Sub UserGrid_RowDeleting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewDeleteEventArgs) Handles UserGrid.RowDeleting

     ' Determine the username of the user we are editing
     Dim UserName As String = UserGrid.DataKeys(e.RowIndex).Value.ToString()

     ' Delete the user
     Membership.DeleteUser(UserName)

     ' Revert the grid's EditIndex to -1 and rebind the data
     UserGrid.EditIndex = -1
     BindUserGrid()
End Sub

Le gestionnaire d’événements ci-dessus commence par saisir la UserName valeur de la collection GridView DataKeys ; cette UserName valeur est ensuite passée à la méthode de DeleteUserla classe Membership. La DeleteUser méthode supprime le compte d’utilisateur du système, y compris les données d’appartenance associées (telles que les rôles auxquels cet utilisateur appartient). Après avoir supprimé l’utilisateur, la grille est EditIndex définie sur -1 (dans le cas où l’utilisateur a cliqué sur Supprimer alors qu’une autre ligne était en mode édition) et la BindUserGrid méthode est appelée.

Notes

Le bouton Supprimer ne nécessite aucune confirmation de la part de l’utilisateur avant de supprimer le compte d’utilisateur. Je vous encourage à ajouter une forme de confirmation d’utilisateur pour réduire le risque de suppression accidentelle d’un compte. 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.

Vérifiez que cette page fonctionne comme prévu. Vous devez être en mesure de modifier l’adresse e-mail et le commentaire d’un utilisateur, ainsi que de supprimer n’importe quel compte d’utilisateur. Étant donné que la RoleBasedAuthorization.aspx page est accessible à tous les utilisateurs, tout utilisateur , même les visiteurs anonymes, peut visiter cette page et modifier et supprimer des comptes d’utilisateur ! Mettons à jour cette page afin que seuls les utilisateurs des rôles Superviseurs et Administrateurs puissent modifier l’adresse e-mail et les commentaires d’un utilisateur, et seuls les administrateurs peuvent supprimer un compte d’utilisateur.

La section « Utilisation du contrôle LoginView » examine l’utilisation du contrôle LoginView pour afficher des instructions spécifiques au rôle de l’utilisateur. Si une personne du rôle Administrateurs visite cette page, nous afficherons des instructions sur la façon de modifier et de supprimer des utilisateurs. Si un utilisateur du rôle Superviseurs atteint cette page, nous afficherons des instructions sur la modification des utilisateurs. Et si le visiteur est anonyme ou n’est pas dans le rôle Superviseurs ou Administrateurs, nous afficherons un message expliquant qu’il ne peut pas modifier ou supprimer les informations de compte d’utilisateur. Dans la section « Fonctionnalités de limitation par programmation », nous allons écrire du code qui affiche ou masque par programmation les boutons Modifier et Supprimer en fonction du rôle de l’utilisateur.

Utilisation du contrôle LoginView

Comme nous l’avons vu dans les tutoriels précédents, le contrôle LoginView est utile pour afficher différentes interfaces pour les utilisateurs authentifiés et anonymes, mais le contrôle LoginView peut également être utilisé pour afficher des balises différentes en fonction des rôles de l’utilisateur. Nous allons utiliser un contrôle LoginView pour afficher différentes instructions en fonction du rôle de l’utilisateur qui visite.

Commencez par ajouter un LoginView au-dessus de GridView UserGrid . Comme nous l’avons vu précédemment, le contrôle LoginView a deux modèles intégrés : AnonymousTemplate et LoggedInTemplate. Entrez un bref message dans ces deux modèles qui informe l’utilisateur qu’il ne peut pas modifier ou supprimer des informations utilisateur.

<asp:LoginView ID="LoginView1" runat="server">
     <LoggedInTemplate>
          You are not a member of the Supervisors or Administrators roles. Therefore you
           cannot edit or delete any user information.
     </LoggedInTemplate>
     <AnonymousTemplate>

          You are not logged into the system. Therefore you cannot edit or delete any user
           information.
     </AnonymousTemplate>
</asp:LoginView>

En plus de et AnonymousTemplateLoggedInTemplate, le contrôle LoginView peut inclure des RoleGroups, qui sont des modèles spécifiques au rôle. Chaque RoleGroup contient une propriété unique, Roles, qui spécifie les rôles auxquels le RoleGroup s’applique. La Roles propriété peut être définie sur un rôle unique (comme « Administrateurs ») ou sur une liste délimitée par des virgules de rôles (comme « Administrateurs, superviseurs »).

Pour gérer les RoleGroups, cliquez sur le lien « Modifier les groupes de rôles » à partir de la balise intelligente du contrôle pour afficher l’éditeur de collection RoleGroup. Ajoutez deux nouveaux RoleGroups. Définissez la propriété du Roles premier RoleGroup sur « Administrateurs » et la seconde sur « Superviseurs ».

Gérer les modèles de Role-Specific de LoginView via l’éditeur de collection RoleGroup

Figure 8 : Gérer les modèles Role-Specific de LoginView à l’aide de l’éditeur de collection RoleGroup (cliquer pour afficher l’image en taille réelle)

Cliquez sur OK pour fermer l’éditeur de collection RoleGroup ; cela met à jour le balisage déclaratif de LoginView pour inclure une section avec un <RoleGroups><asp:RoleGroup> élément enfant pour chaque RoleGroup défini dans l’éditeur de collection RoleGroup. En outre, la liste déroulante « Vues » dans la balise smart de LoginView , qui ne listait initialement que les AnonymousTemplate et LoggedInTemplate , inclut désormais les groupes de rôles ajoutés.

Modifiez les groupes de rôles afin que les utilisateurs du rôle Superviseurs affichent des instructions sur la façon de modifier les comptes d’utilisateur, tandis que les utilisateurs du rôle Administrateurs affichent des instructions de modification et de suppression. Après avoir apporté ces modifications, le balisage déclaratif de votre LoginView doit ressembler à ce qui suit.

<asp:LoginView ID="LoginView1" runat="server">
     <RoleGroups>
          <asp:RoleGroup Roles="Administrators">

               <ContentTemplate>
                    As an Administrator, you may edit and delete user accounts. 
                    Remember: With great power comes great responsibility!
               </ContentTemplate>
          </asp:RoleGroup>
          <asp:RoleGroup Roles="Supervisors">
               <ContentTemplate>
                    As a Supervisor, you may edit users&#39; Email and Comment information. 
                    Simply click the Edit button, make your changes, and then click Update.
               </ContentTemplate>

          </asp:RoleGroup>
     </RoleGroups>
     <LoggedInTemplate>
          You are not a member of the Supervisors or Administrators roles. 
          Therefore you cannot edit or delete any user information.
     </LoggedInTemplate>
     </AnonymousTemplate>
          You are not logged into the system. 
          Therefore you cannot edit or delete any user information.
     </AnonymousTemplate>
</asp:LoginView>

Après avoir apporté ces modifications, enregistrez la page, puis visitez-la via un navigateur. Commencez par visiter la page en tant qu’utilisateur anonyme. Le message « Vous n’êtes pas connecté au système doit s’afficher. Par conséquent, vous ne pouvez pas modifier ou supprimer des informations utilisateur. » Connectez-vous ensuite en tant qu’utilisateur authentifié, mais qui n’est ni dans le rôle Superviseurs ni Administrateurs. Cette fois, vous devriez voir le message « Vous n’êtes pas membre des rôles Superviseurs ou Administrateurs. Par conséquent, vous ne pouvez pas modifier ou supprimer des informations utilisateur. »

Ensuite, connectez-vous en tant qu’utilisateur membre du rôle Superviseurs. Cette fois, vous devez voir le message spécifique au rôle superviseur (voir figure 9). Et si vous vous connectez en tant qu’utilisateur dans le rôle Administrateurs, vous devez voir le message spécifique au rôle Administrateurs (voir figure 10).

Bruce affiche le message Role-Specific superviseurs

Figure 9 : Bruce affiche le message Role-Specific superviseurs (cliquer pour afficher l’image en taille réelle)

Tito affiche le message Role-Specific administrateurs

Figure 10 : Tito affiche le message Role-Specific administrateurs (cliquez pour afficher l’image en taille réelle)

Comme le montrent les captures d’écran des figures 9 et 10, LoginView affiche un seul modèle, même si plusieurs modèles s’appliquent. Bruce et Tito sont tous deux des utilisateurs connectés, mais LoginView affiche uniquement le RoleGroup correspondant et non le LoggedInTemplate. En outre, Tito appartient aux rôles Administrateurs et Superviseurs, mais le contrôle LoginView affiche le modèle spécifique au rôle Administrateurs au lieu de celui des superviseurs.

La figure 11 illustre le flux de travail utilisé par le contrôle LoginView pour déterminer le modèle à afficher. Notez que si plusieurs RoleGroup sont spécifiés, le modèle LoginView affiche le premier RoleGroup correspondant. En d’autres termes, si nous avions placé le RoleGroup des superviseurs en tant que premier RoleGroup et les Administrateurs comme deuxième, alors quand Tito a visité cette page, il voyait le message Superviseurs.

Flux de travail du contrôle LoginView pour déterminer le modèle à afficher

Figure 11 : Workflow du contrôle LoginView pour déterminer le modèle à afficher (cliquez pour afficher l’image en taille réelle)

Fonctionnalité de limitation par programme

Bien que le contrôle LoginView affiche des instructions différentes en fonction du rôle de l’utilisateur qui visite la page, les boutons Modifier et Annuler restent visibles par tous. Nous devons masquer par programmation les boutons Modifier et Supprimer pour les visiteurs et utilisateurs anonymes qui ne sont ni dans le rôle Superviseurs ni Administrateurs. Nous devons masquer le bouton Supprimer pour tous ceux qui ne sont pas administrateurs. Pour ce faire, nous allons écrire un peu de code qui fait référence par programmation aux éléments Edit et Delete LinkButtons de CommandField et définit leurs Visible propriétés sur False, si nécessaire.

Le moyen le plus simple de référencer des contrôles par programmation dans un Champ de commandes consiste à les convertir d’abord en modèle. Pour ce faire, cliquez sur le lien « Modifier les colonnes » à partir de la balise intelligente de GridView, sélectionnez commandField dans la liste des champs actuels, puis cliquez sur le lien « Convertir ce champ en champ de modèle ». Cela transforme commandField en templateField avec et ItemTemplateEditItemTemplate. contient ItemTemplate les éléments Edit et Delete LinkButtons tandis que le EditItemTemplate contient les éléments Update et Cancel LinkButtons.

Convertir le champ de commandes en un champ de modèle

Figure 12 : Convertir le champ de commande en un champ de modèle (cliquez pour afficher l’image en taille réelle)

Mettez à jour les éléments Edit et Delete LinkButton dans , ItemTemplateen définissant leurs ID propriétés sur les valeurs de EditButton et DeleteButton, respectivement.

<asp:TemplateField ShowHeader="False">
     <EditItemTemplate>
          <asp:LinkButton ID="LinkButton1" runat="server" CausesValidation="True" 
               CommandName="Update" Text="Update"></asp:LinkButton>

           <asp:LinkButton ID="LinkButton2" runat="server" CausesValidation="False"
               CommandName="Cancel" Text="Cancel"></asp:LinkButton>

     </EditItemTemplate>
     <ItemTemplate>
          <asp:LinkButton ID="EditButton" runat="server" CausesValidation="False" 
               CommandName="Edit" Text="Edit"></asp:LinkButton>

           <asp:LinkButton ID="DeleteButton" runat="server" CausesValidation="False"
               CommandName="Delete" Text="Delete"></asp:LinkButton>

     </ItemTemplate>
</asp:TemplateField>

Chaque fois que des données sont liées à GridView, gridView énumère les enregistrements dans sa DataSource propriété et génère un objet correspondant GridViewRow . À mesure que chaque GridViewRow objet est créé, l’événement RowCreated est déclenché. Pour masquer les boutons Modifier et Supprimer pour les utilisateurs non autorisés, nous devons créer un gestionnaire d’événements pour cet événement et référencer par programmation les boutons Modifier et supprimer les linkButtons, en définissant leurs Visible propriétés en conséquence.

Créez un gestionnaire d’événements pour l’événement RowCreated , puis ajoutez le code suivant :

Protected Sub UserGrid_RowCreated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles UserGrid.RowCreated
     If e.Row.RowType = DataControlRowType.DataRow AndAlso e.Row.RowIndex <> UserGrid.EditIndex Then
          ' Programmatically reference the Edit and Delete LinkButtons
          Dim EditButton As LinkButton = CType(e.Row.FindControl("EditButton"), LinkButton)

          Dim DeleteButton As LinkButton = CType(e.Row.FindControl("DeleteButton"), LinkButton)

          EditButton.Visible = (User.IsInRole("Administrators") OrElse User.IsInRole("Supervisors"))
          DeleteButton.Visible = User.IsInRole("Administrators")
     End If
End Sub

N’oubliez pas que l’événement RowCreated se déclenche pour toutes les lignes GridView, y compris l’en-tête, le pied de page, l’interface du pagineur, etc. Nous voulons uniquement référencer par programmation les boutons Modifier et Supprimer linkButtons si nous avons affaire à une ligne de données qui n’est pas en mode édition (car la ligne en mode édition comporte des boutons Mettre à jour et Annuler au lieu de Modifier et Supprimer). Cette case activée est gérée par l’instruction If .

Si nous avons affaire à une ligne de données qui n’est pas en mode édition, les éléments Edit et Delete LinkButtons sont référencés et leurs Visible propriétés sont définies en fonction des valeurs booléennes retournées par la méthode de IsInRole(roleName) l’objetUser. L’objet User fait référence au principal créé par ; RoleManagerModulepar conséquent, la IsInRole(roleName) méthode utilise l’API Rôles pour déterminer si le visiteur actuel appartient à roleName.

Notes

Nous aurions pu utiliser directement la classe Roles, en remplaçant l’appel à User.IsInRole(roleName) par un appel à la Roles.IsUserInRole(roleName) méthode. J’ai décidé d’utiliser la méthode de IsInRole(roleName) l’objet principal dans cet exemple, car elle est plus efficace que d’utiliser l’API Rôles directement. Plus haut dans ce tutoriel, nous avons configuré le gestionnaire de rôles pour mettre en cache les rôles de l’utilisateur dans un cookie. Ces données de cookie mises en cache sont utilisées uniquement lorsque la méthode du IsInRole(roleName) principal est appelée ; les appels directs à l’API Rôles impliquent toujours un déplacement vers le magasin de rôles. Même si les rôles ne sont pas mis en cache dans un cookie, l’appel de la méthode de IsInRole(roleName) l’objet principal est généralement plus efficace, car lorsqu’il est appelé pour la première fois lors d’une requête, il met en cache les résultats. En revanche, l’API Rôles n’effectue aucune mise en cache. Étant donné que l’événement RowCreated est déclenché une fois pour chaque ligne de GridView, l’utilisation User.IsInRole(roleName) implique un seul déplacement dans le magasin de rôles, alors que Roles.IsUserInRole(roleName) nécessite N voyages, où N est le nombre de comptes d’utilisateur affichés dans la grille.

La propriété du Visible bouton Modifier est définie True sur si l’utilisateur qui visite cette page est dans le rôle Administrateurs ou Superviseurs ; sinon, elle a la Falsevaleur . La propriété du Visible bouton Supprimer est définie True sur uniquement si l’utilisateur est dans le rôle Administrateurs.

Testez cette page via un navigateur. Si vous visitez la page en tant que visiteur anonyme ou en tant qu’utilisateur qui n’est ni superviseur ni administrateur, le champ de commande est vide ; il existe toujours, mais en tant que sliver mince sans les boutons Modifier ou Supprimer.

Notes

Il est possible de masquer complètement le champ de commande lorsqu’un non-superviseur et un non-administrateur visitent la page. Je laisse cela comme un exercice pour le lecteur.

Les boutons Modifier et Supprimer sont masqués pour les non-superviseurs et les non-administrateurs

Figure 13 : Les boutons Modifier et Supprimer sont masqués pour les non-superviseurs et les non-administrateurs (cliquer pour afficher l’image en taille réelle)

Si un utilisateur qui appartient au rôle Superviseurs (mais pas au rôle Administrateurs) visite, il voit uniquement le bouton Modifier.

Bien que le bouton Modifier soit disponible pour les superviseurs, le bouton Supprimer est masqué

Figure 14 : Alors que le bouton Modifier est disponible pour les superviseurs, le bouton Supprimer est masqué (cliquez pour afficher l’image en taille réelle)

Et si un administrateur visite, il a accès aux boutons Modifier et Supprimer.

Les boutons Modifier et Supprimer sont disponibles uniquement pour les administrateurs

Figure 15 : Les boutons Modifier et Supprimer sont disponibles uniquement pour les administrateurs (cliquer pour afficher l’image en taille réelle)

Étape 3 : Application de règles d’autorisation Role-Based aux classes et méthodes

À l’étape 2, nous avons limité les fonctionnalités de modification aux utilisateurs dans les rôles Superviseurs et Administrateurs, et les fonctionnalités de suppression aux administrateurs uniquement. Pour ce faire, vous avez masqué les éléments d’interface utilisateur associés pour les utilisateurs non autorisés par le biais de techniques programmatiques. Ces mesures ne garantissent pas qu’un utilisateur non autorisé ne sera pas en mesure d’effectuer une action privilégiée. Il peut y avoir des éléments d’interface utilisateur qui sont ajoutés ultérieurement ou que nous avons oublié de masquer pour les utilisateurs non autorisés. Ou un pirate peut découvrir une autre façon d’obtenir la page ASP.NET pour exécuter la méthode souhaitée.

Un moyen simple de s’assurer qu’un utilisateur non autorisé n’a pas accès à une fonctionnalité particulière consiste à décorer cette classe ou méthode avec l’attributPrincipalPermission . Lorsque le runtime .NET utilise une classe ou exécute l’une de ses méthodes, il vérifie que le contexte de sécurité actuel dispose de l’autorisation. L’attribut PrincipalPermission fournit un mécanisme par lequel nous pouvons définir ces règles.

Nous avons examiné l’utilisation de l’attribut PrincipalPermission dans le didacticiel Sur l’autorisation basée sur l’utilisateur. Plus précisément, nous avons vu comment décorer les gestionnaires d’événements gridView et RowDeleting afin qu’ils SelectedIndexChanged ne puissent être exécutés que par des utilisateurs authentifiés et par Tito, respectivement. L’attribut PrincipalPermission fonctionne tout aussi bien avec les rôles.

Nous allons illustrer l’utilisation de l’attribut PrincipalPermission sur les gestionnaires d’événements gridView et RowDeleting pour interdire l’exécution RowUpdating pour les utilisateurs non autorisés. Tout ce que nous devons faire est d’ajouter l’attribut approprié au-dessus de chaque définition de fonction :

<PrincipalPermission(SecurityAction.Demand, Role:="Administrators")>_
<PrincipalPermission(SecurityAction.Demand, Role:="Supervisors")>_
Protected Sub UserGrid_RowUpdating(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewUpdateEventArgs) Handles UserGrid.RowUpdating
     ...
End Sub

<PrincipalPermission(SecurityAction.Demand, Role:="Administrators")>_
Protected Sub UserGrid_RowDeleting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewDeleteEventArgs) Handles UserGrid.RowDeleting
     ...
End Sub

L’attribut du RowUpdating gestionnaire d’événements dicte que seuls les utilisateurs des rôles Administrateurs ou Superviseurs peuvent exécuter le gestionnaire d’événements, où en tant qu’attribut sur le RowDeleting gestionnaire d’événements limite l’exécution aux utilisateurs dans le rôle Administrateurs.

Notes

L’attribut PrincipalPermission est représenté sous la forme d’une classe dans l’espace de System.Security.Permissions noms . Veillez à ajouter une Imports System.Security.Permissions instruction en haut de votre fichier de classe code-behind pour importer cet espace de noms.

Si, en quelque sorte, un non-administrateur tente d’exécuter le RowDeleting gestionnaire d’événements ou si un non-superviseur ou un non-administrateur tente d’exécuter le RowUpdating gestionnaire d’événements, le runtime .NET déclenche un SecurityException.

Si le contexte de sécurité n’est pas autorisé à exécuter la méthode, une exception SecurityException est levée.

Figure 16 : Si le contexte de sécurité n’est pas autorisé à exécuter la méthode, un SecurityException est levée (cliquez pour afficher l’image en taille réelle)

En plus de ASP.NET pages, de nombreuses applications ont également une architecture qui inclut différentes couches, telles que la logique métier et les couches d’accès aux données. Ces couches sont généralement implémentées en tant que bibliothèques de classes et offrent des classes et des méthodes pour exécuter des fonctionnalités liées à la logique métier et aux données. L’attribut PrincipalPermission est également utile pour appliquer des règles d’autorisation à ces couches.

Pour plus d’informations sur l’utilisation de l’attribut PrincipalPermission pour définir des règles d’autorisation sur les classes et les méthodes, reportez-vous à l’entrée de blog de Scott GuthrieAjout de règles d’autorisation aux couches de données et d’entreprise à l’aide PrincipalPermissionAttributesde .

Résumé

Dans ce tutoriel, nous avons vu comment spécifier des règles d’autorisation grossières et précises en fonction des rôles de l’utilisateur. ASP. La fonctionnalité d’autorisation d’URL de NET permet à un développeur de pages de spécifier quelles identités sont autorisées ou refusées l’accès à quelles pages. Comme nous l’avons vu dans le didacticiel Sur l’autorisation basée sur l’utilisateur, les règles d’autorisation d’URL peuvent être appliquées utilisateur par utilisateur. Elles peuvent également être appliquées rôle par rôle, comme nous l’avons vu à l’étape 1 de ce tutoriel.

Les règles d’autorisation de grains fins peuvent être appliquées de manière déclarative ou programmatique. À l’étape 2, nous avons examiné l’utilisation de la fonctionnalité RoleGroups du contrôle LoginView pour afficher une sortie différente en fonction des rôles de l’utilisateur qui visite. Nous avons également examiné comment déterminer par programmation si un utilisateur appartient à un rôle spécifique et comment ajuster les fonctionnalités de la page en conséquence.

Bonne programmation !

En savoir plus

Pour plus d’informations sur les sujets abordés dans ce didacticiel, consultez les 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 Hours. Scott peut être joint à l’adresse 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. Les réviseurs principaux de ce tutoriel incluent Suchi Banerjee et Teresa Murphy. Vous souhaitez consulter mes prochains articles MSDN ? Si c’est le cas, déposez-moi une ligne à mitchell@4GuysFromRolla.com