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.
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)
Mise en cache des informations de rôle dans un cookie
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 RolePrincipal
mé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 EndRequest
pipeline 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.
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 to
true. | |
cookieTimeout | Specifies the time, in minutes, after which the authentication ticket cookie expires. The default value is
30. This value is only pertinent when
createPersistentCookieis set to
true. | |
createPersistentCookie | A Boolean value that specifies whether the role cache cookie is a session cookie or persistent cookie. If
false(the default), a session cookie is used, which is deleted when the browser is closed. If
true, a persistent cookie is used; it expires
cookieTimeoutnumber of minutes after it has been created or after the previous visit, depending on the value of
cookieSlidingExpiration. | |
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 the
maxCachedResults | Specifies the maximum number of role names that are cached in the cookie. The default is 25. The
RoleManagerModuledoes not create a cookie for users that belong to more than
maxCachedResultsroles. Consequently, the
RolePrincipalobject's
IsInRolemethod will use the
Rolesclass to determine the user's roles. The reason
maxCachedResultsexists 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
, createPersistentCookie
et 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.aspx
pages , UsersAndRoles.aspx
et 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 .
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.
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.
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
,Email
LastLoginDate
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 UserName
propriétés , Email
, LastLoginDate
et 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 ».
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.
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
, RowUpdating
et 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 , RowCancelingEdit
et RowUpdating
de RowEditing
GridView, 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 DeleteUser
la 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 AnonymousTemplate
LoggedInTemplate
, 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 ».
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' 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).
Figure 9 : Bruce affiche le message Role-Specific superviseurs (cliquer pour afficher l’image en taille réelle)
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.
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 ItemTemplate
EditItemTemplate
. contient ItemTemplate
les éléments Edit et Delete LinkButtons tandis que le EditItemTemplate
contient les éléments Update et Cancel LinkButtons.
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 , ItemTemplate
en 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 ; RoleManagerModule
par 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 False
valeur . 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.
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.
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.
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
.
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 PrincipalPermissionAttributes
de .
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 :
- Ajout de règles d’autorisation aux couches d’entreprise et de données à l’aide de
PrincipalPermissionAttributes
- Examen de l’appartenance, des rôles et du profil de ASP.NET 2.0 : utilisation des rôles
- Liste des questions de sécurité pour ASP.NET 2.0
- Documentation technique pour l’élément
<roleManager>
À 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