Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Annotazioni
Poiché questo articolo è stato scritto, i provider di appartenenza ASP.NET sono stati sostituiti da ASP.NET Identity. Si raccomanda fortemente di aggiornare le app per usare la piattaforma ASP.NET Identity anziché i provider di Membership presenti al momento della scrittura di questo articolo. ASP.NET Identity offre numerosi vantaggi rispetto al sistema di appartenenza ASP.NET, tra cui :
- Prestazioni migliori
- Estendibilità e testbilità migliorate
- Supporto per OAuth, OpenID Connect e autenticazione a due fattori
- Supporto per le identità basate su attestazioni
- Migliore interoperabilità con ASP.Net Core
Scaricare codice o Scaricare PDF
Questa esercitazione inizia con un'analisi del modo in cui il framework Ruoli associa i ruoli di un utente al contesto di sicurezza. Viene quindi esaminato come applicare regole di autorizzazione URL basate su ruoli. In seguito, si esaminerà l'uso di mezzi dichiarativi e programmatici per modificare i dati visualizzati e le funzionalità offerte da una pagina ASP.NET.
Introduzione
Nell'esercitazione sull'autorizzazione User-Based è stato illustrato come usare l'autorizzazione URL per specificare quali utenti possono visitare un determinato set di pagine. Con solo un po' di markup in Web.config, è possibile indicare ASP.NET di consentire solo agli utenti autenticati di visitare una pagina. Oppure potremmo stabilire che solo gli utenti Tito e Bob siano consentiti, o indicare che tutti gli utenti autenticati tranne Sam siano consentiti.
Oltre all'autorizzazione url, sono state esaminate anche tecniche dichiarative e programmatice per controllare i dati visualizzati e le funzionalità offerte da una pagina in base alla visita dell'utente. In particolare, è stata creata una pagina che elenca il contenuto della directory corrente. Chiunque può visitare questa pagina, ma solo gli utenti autenticati potrebbero visualizzare il contenuto dei file e solo Tito potrebbe eliminare i file.
L'applicazione di regole di autorizzazione su base utente può crescere in un incubo di contabilità. Un approccio più gestibile consiste nell'usare l'autorizzazione basata sui ruoli. La buona notizia è che gli strumenti a disposizione per l'applicazione delle regole di autorizzazione funzionano altrettanto bene con i ruoli che fanno per gli account utente. Le regole di autorizzazione URL possono specificare ruoli anziché utenti. Il controllo LoginView, che esegue il rendering di output diverso per gli utenti autenticati e anonimi, può essere configurato per visualizzare contenuto diverso in base ai ruoli dell'utente connesso. E l'API Ruoli include metodi per determinare i ruoli dell'utente connesso.
Questa esercitazione inizia con un'analisi del modo in cui il framework Ruoli associa i ruoli di un utente al contesto di sicurezza. Viene quindi esaminato come applicare regole di autorizzazione URL basate su ruoli. In seguito, si esaminerà l'uso di mezzi dichiarativi e programmatici per modificare i dati visualizzati e le funzionalità offerte da una pagina ASP.NET. È ora di iniziare.
Informazioni su come i ruoli sono associati al contesto di sicurezza di un utente
Ogni volta che una richiesta entra nella pipeline di ASP.NET associata a un contesto di sicurezza, che include informazioni che identificano il richiedente. Quando si usa l'autenticazione basata su form, un ticket di autenticazione viene usato come token di identità. Come illustrato nell'esercitazione Una panoramica dell'autenticazione tramite form, FormsAuthenticationModule è responsabile della determinazione dell'identità del richiedente, che esegue durante l'evento AuthenticateRequest.
Se viene trovato un ticket di autenticazione valido e non scaduto, FormsAuthenticationModule lo decodifica per verificare l'identità del richiedente. Crea un nuovo GenericPrincipal oggetto e lo assegna all'oggetto HttpContext.User . Lo scopo di un principale, come GenericPrincipal, è identificare il nome dell'utente autenticato e il ruolo a cui appartiene. Questo scopo è evidente dal fatto che tutti gli oggetti principal hanno una Identity proprietà e un IsInRole(roleName) metodo. L'oggetto FormsAuthenticationModule, tuttavia, non è interessato alla registrazione delle informazioni sul ruolo e l'oggetto GenericPrincipal creato non specifica alcun ruolo.
Se il framework dei ruoli è abilitato, il RoleManagerModule modulo HTTP interviene dopo il FormsAuthenticationModule e identifica i ruoli dell'utente autenticato durante l'evento di PostAuthenticateRequest, che si attiva dopo l'evento AuthenticateRequest. Se la richiesta proviene da un utente autenticato, l'oggetto RoleManagerModule sovrascrive l'oggetto GenericPrincipal creato da FormsAuthenticationModule e lo sostituisce con un RolePrincipal oggetto . La RolePrincipal classe usa l'API Roles per determinare i ruoli a cui appartiene l'utente.
La figura 1 illustra il flusso di lavoro della pipeline ASP.NET quando si usa l'autenticazione basata su form e il framework Ruoli. "FormsAuthenticationModule viene eseguito per primo, identifica l'utente tramite il suo ticket di autenticazione e crea una nuova istanza di GenericPrincipal." Successivamente, il RoleManagerModule entra e sovrascrive l'oggetto GenericPrincipal con un RolePrincipal oggetto.
Se un utente anonimo visita il sito, né il FormsAuthenticationModule né il RoleManagerModule creano un oggetto principale.
Figura 1: Eventi della pipeline ASP.NET per un utente autenticato quando si usa l'autenticazione basata su form e il framework dei ruoli (fare clic per visualizzare l'immagine a dimensione intera)
Memorizzazione nella cache delle informazioni sui ruoli in un cookie
Il RolePrincipal metodo dell'oggetto IsInRole(roleName) chiama Roles.
GetRolesForUser per ottenere i ruoli per l'utente per determinare se l'utente è membro di roleName. Quando si usa SqlRoleProvider, viene generata una query nel database dell'archivio dei ruoli. Quando si usano regole di autorizzazione url basate su ruoli, il RolePrincipalmetodo viene IsInRole chiamato in ogni richiesta a una pagina protetta dalle regole di autorizzazione dell'URL basate su ruoli. Anziché dover cercare le informazioni sul ruolo nel database in ogni richiesta, il Roles framework include un'opzione per memorizzare nella cache i ruoli dell'utente in un cookie.
Se il framework Ruoli è configurato per memorizzare nella cache i ruoli dell'utente in un cookie, il RoleManagerModule crea il cookie durante l'evento EndRequest della pipeline ASP.NET. Questo cookie viene usato nelle richieste successive in PostAuthenticateRequest, ovvero quando viene creato l'oggetto RolePrincipal . Se il cookie è valido e non è scaduto, i dati nel cookie vengono analizzati e usati per popolare i ruoli dell'utente, evitando così di RolePrincipal dover effettuare una chiamata alla Roles classe per determinare i ruoli dell'utente. La figura 2 illustra questo flusso di lavoro.
Figura 2: Le informazioni sul ruolo dell'utente possono essere archiviate in un cookie per migliorare le prestazioni (fare clic per visualizzare l'immagine a dimensione intera)
Per impostazione predefinita, il meccanismo dei cookie della cache dei ruoli è disabilitato. Può essere abilitata tramite il markup di configurazione <roleManager> in Web.config. Abbiamo discusso dell'uso dell'elemento <roleManager> per specificare i provider di ruoli nel tutorial Creazione e gestione dei ruoli, quindi dovresti già avere questo elemento nel file dell'applicazioneWeb.config. Le impostazioni dei cookie della cache dei ruoli vengono specificate come attributi dell'elemento <roleManager>; e sono riepilogate nella tabella 1.
Annotazioni
Le impostazioni di configurazione elencate nella tabella 1 specificano le proprietà del cookie della cache dei ruoli risultante. Per altre informazioni sui cookie, sul loro funzionamento e sulle relative varie proprietà, leggere questa esercitazione sui cookie.
| Proprietà | Descrizione |
|---|---|
cacheRolesInCookie |
Valore booleano che indica se viene utilizzata la memorizzazione nella cache dei cookie. Il valore predefinito è false. |
cookieName |
Nome del cookie di cache del ruolo. Il valore predefinito è ". ASPXROLES". |
cookiePath |
Percorso del cookie del nome dei ruoli. L'attributo path consente a uno sviluppatore di limitare l'ambito di un cookie a una determinata gerarchia di directory. Il valore predefinito è "/", che informa il browser di inviare il cookie del ticket di autenticazione a qualsiasi richiesta effettuata al dominio. |
cookieProtection |
Indica quali tecniche vengono usate per proteggere il cookie della cache dei ruoli. I valori consentiti sono: All (impostazione predefinita); Encryption; None; e Validation.md) |
|
cookieRequireSSL | Valore booleano che indica se è necessaria una connessione SSL per trasmettere il cookie di autenticazione. Il valore predefinito è false. | | cookieSlidingExpiration | 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 isfalse. This value is only pertinent when 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. | | domain| 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 thedomainattribute, setting it to "yourdomain.com". | | maxCachedResults | 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 smallervalore di maxCachedResults; contrariamente, se si dispone di nomi di ruolo estremamente brevi, probabilmente è possibile aumentare questo valore. |
Tabella 1: Opzioni di configurazione dei cookie della cache dei ruoli
Configuriamo l'applicazione per utilizzare i cookie della cache dei ruoli non persistenti. A tale scopo, aggiornare l'elemento <roleManager> in Web.config per includere gli attributi correlati ai cookie seguenti:
<roleManager enabled="true"
defaultProvider="SecurityTutorialsSqlRoleProvider"
cacheRolesInCookie="true"
createPersistentCookie="false"
cookieProtection="All">
<providers>
...
</providers>
</roleManager>
Ho aggiornato l'elemento <roleManager>; aggiungendo tre attributi: cacheRolesInCookie, createPersistentCookiee cookieProtection. Impostando cacheRolesInCookie su true, l'oggetto RoleManagerModule ora memorizza automaticamente nella cache i ruoli dell'utente in un cookie anziché dover cercare le informazioni sul ruolo dell'utente in ogni richiesta. Imposto esplicitamente gli attributi createPersistentCookie e cookieProtection rispettivamente su false e All. Tecnicamente, non ho dovuto specificare i valori per questi attributi perché li ho appena assegnati ai valori predefiniti, ma li ho messi qui per rendere esplicitamente chiaro che non uso cookie persistenti e che il cookie sia crittografato e convalidato.
Ecco fatto! D'ora in poi, il framework Ruoli memorizzerà nella cache i ruoli degli utenti nei cookie. Se il browser dell'utente non supporta i cookie o se i cookie vengono eliminati o persi, in qualche modo, non è un grosso problema: l'oggetto RolePrincipal userà semplicemente la Roles classe nel caso in cui non sia disponibile alcun cookie (o un cookie non valido o scaduto).
Annotazioni
Il gruppo Patterns & Practices di Microsoft sconsiglia l'uso di cookie di cache dei ruoli permanenti. Poiché il possesso del cookie della cache del ruolo è sufficiente per dimostrare l'appartenenza al ruolo, se un hacker può in qualche modo ottenere l'accesso al cookie di un utente valido può rappresentare tale utente. La probabilità che ciò accada aumenta se il cookie viene salvato in modo permanente nel browser dell'utente. Per altre informazioni su questa raccomandazione di sicurezza, oltre ad altri problemi di sicurezza, vedere l'elenco delle domande di sicurezza per ASP.NET 2.0.
Passaggio 1: Definizione delle regole di autorizzazione URL basate sui ruoli
Come illustrato nell'esercitazione sull'Autorizzazione Basata su Utente, l'autorizzazione URL offre un modo per limitare l'accesso a un set di pagine per utente o per ruolo. Le regole di autorizzazione URL sono esplicitate in Web.config usando l'elemento <authorization> con gli elementi figlio <allow> e <deny>. Oltre alle regole di autorizzazione correlate all'utente discusse nelle esercitazioni precedenti, ogni elemento figlio <allow> e <deny> può anche includere:
- Un ruolo specifico
- Elenco di ruoli delimitato da virgole
Ad esempio, le regole di autorizzazione URL concedono l'accesso a tali utenti nei ruoli Amministratori e Supervisori, ma negano l'accesso a tutti gli altri:
<authorization>
<allow roles="Administrators, Supervisors" />
<deny users="*" />
</authorization>
L'elemento <allow> nel markup precedente indica che i ruoli Administrators e Supervisors sono consentiti; l'elemento <deny>; indica che tutti gli utenti vengono negati.
Configurare l'applicazione in modo che le ManageRoles.aspxpagine , UsersAndRoles.aspxe CreateUserWizardWithRoles.aspx siano accessibili solo agli utenti nel ruolo Amministratori, mentre la RoleBasedAuthorization.aspx pagina rimane accessibile a tutti i visitatori.
A tale scopo, iniziare aggiungendo un Web.config file alla Roles cartella .
Figura 3: Aggiungere un Web.config file alla Roles directory (fare clic per visualizzare l'immagine a dimensione intera)
Aggiungere quindi il markup di configurazione seguente a 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'elemento <authorization> nella <system.web> sezione indica che solo gli utenti nel ruolo Administrators possono accedere alle risorse ASP.NET nella Roles directory. L'elemento <location> definisce un set alternativo di regole di autorizzazione URL per la RoleBasedAuthorization.aspx pagina, consentendo a tutti gli utenti di visitare la pagina.
Dopo aver salvato le modifiche in Web.config, accedere come utente che non è nel ruolo Administrators e quindi provare a visitare una delle pagine protette. Rileverà UrlAuthorizationModule che non si dispone dell'autorizzazione per visitare la risorsa richiesta. Di conseguenza, FormsAuthenticationModule verrà reindirizzato alla pagina di accesso. La pagina di accesso reindirizzerà quindi alla UnauthorizedAccess.aspx pagina (vedere figura 4). Questo reindirizzamento finale dalla pagina di accesso a UnauthorizedAccess.aspx se la stringa di query contiene un ReturnUrl parametro, in quanto questo parametro indica che l'utente è arrivato alla pagina di accesso dopo aver tentato di visualizzare una pagina che non è stato autorizzato a visualizzare.
Figura 4: Solo gli utenti nel ruolo Administrators possono visualizzare le pagine protette (fare clic per visualizzare l'immagine a dimensione intera)
Disconnettiti e quindi accedi come utente con il ruolo di amministratore. A questo momento dovrebbe essere possibile visualizzare le tre pagine protette.
Figura 5: Tito può visitare la UsersAndRoles.aspx pagina perché è nel ruolo amministratori (fare clic per visualizzare l'immagine a dimensione intera)
Annotazioni
Quando si specificano regole di autorizzazione URL, per ruoli o utenti, è importante tenere presente che le regole vengono analizzate una alla volta, dall'alto verso il basso. Non appena viene trovata una corrispondenza, all'utente viene concesso o negato l'accesso, a seconda che la corrispondenza sia stata trovata in un <allow> elemento o <deny> . Se non viene trovata alcuna corrispondenza, all'utente viene concesso l'accesso. Di conseguenza, se si vuole limitare l'accesso a uno o più account utente, è fondamentale usare un <deny> elemento come ultimo elemento nella configurazione dell'autorizzazione URL.
Se le regole di autorizzazione URL non includono un<deny>elemento, tutti gli utenti otterranno l'accesso. Per un'analisi più approfondita sul modo in cui vengono analizzate le regole di autorizzazione URL, vedere la sezione "Una panoramica su come il UrlAuthorizationModule usa le regole di autorizzazione per concedere o negare l'accesso" del tutorial Autorizzazione Basata su Utente.
Passaggio 2: Limitazione delle funzionalità in base ai ruoli dell'utente attualmente connessi
L'autorizzazione URL consente di specificare facilmente regole di autorizzazione grossolane che indicano quali identità sono consentite e quali sono negate dalla visualizzazione di una pagina specifica (o di tutte le pagine di una cartella e delle relative sottocartelle). In alcuni casi, tuttavia, è possibile consentire a tutti gli utenti di visitare una pagina, ma limitare le funzionalità della pagina in base ai ruoli dell'utente in visita. Ciò può comportare la visualizzazione o la nascondere i dati in base al ruolo dell'utente o offrire funzionalità aggiuntive agli utenti che appartengono a un ruolo specifico.
Tali regole di autorizzazione granulari basate sui ruoli possono essere implementate in modo dichiarativo o programmatico (o tramite una combinazione dei due). Nella sezione successiva verrà illustrato come implementare l'autorizzazione granulare dichiarativa tramite il controllo LoginView. A questo scopo, verranno esaminate le tecniche a livello di codice. Prima di poter esaminare l'applicazione di regole di autorizzazione con granularità fine, è prima necessario creare una pagina la cui funzionalità dipende dal ruolo dell'utente che lo visita.
Verrà ora creata una pagina che elenca tutti gli account utente nel sistema in un controllo GridView. GridView includerà il nome utente, l'indirizzo di posta elettronica, la data dell'ultimo accesso e i commenti dell'utente. Oltre a visualizzare le informazioni di ogni utente, GridView includerà funzionalità di modifica ed eliminazione. Verrà inizialmente creata questa pagina con la funzionalità di modifica ed eliminazione disponibile per tutti gli utenti. Nelle sezioni "Using the LoginView Control" e "Programmatically Limiting Functionality" (Uso del controllo LoginView) e "Limitazione a livello di codice" si vedrà come abilitare o disabilitare queste funzionalità in base al ruolo dell'utente in visita.
Annotazioni
La pagina ASP.NET che stiamo per compilare usa un controllo GridView per visualizzare gli account utente. Poiché questa serie di esercitazioni è incentrata sull'autenticazione dei moduli, l'autorizzazione, gli account utente e i ruoli, non voglio dedicare troppo tempo a discutere i lavori interni del controllo GridView. Anche se questa esercitazione fornisce istruzioni dettagliate specifiche per la configurazione di questa pagina, non illustra i dettagli del motivo per cui sono state effettuate determinate scelte o quali effetti hanno determinate proprietà sull'output sottoposto a rendering. Per un esame approfondito del controllo GridView, consultare la mia serie di esercitazioni Working with Data in ASP.NET 2.0.
Per iniziare, aprire la RoleBasedAuthorization.aspx pagina nella Roles cartella . Trascinare un controllo GridView dalla pagina al Designer e impostare il suo ID su UserGrid. Tra un attimo scriveremo il codice che chiama il Membership.
GetAllUsers metodo e associa l'oggetto risultante MembershipUserCollection a GridView. Contiene un MembershipUserCollection oggetto per ogni account utente nel sistema. MembershipUser Gli MembershipUser oggetti hanno proprietà come UserName,EmailLastLoginDate e così via.
Prima di scrivere il codice che associa gli account utente alla griglia, definire prima i campi di GridView. Dallo smart tag di GridView fare clic sul collegamento "Modifica colonne" per avviare la finestra di dialogo Campi (vedere la figura 6). Da qui deselezionare la casella di controllo "Genera automaticamente campi" nell'angolo in basso a sinistra. Poiché vogliamo che questo GridView includa funzionalità di modifica ed eliminazione, aggiungere un oggetto CommandField e impostarne le proprietà ShowEditButton e ShowDeleteButton su True. Aggiungere quindi quattro campi per visualizzare le proprietà UserName, Email, LastLoginDate e Comment. Usare boundfield per le due proprietà di sola lettura (UserName e LastLoginDate) e TemplateFields per i due campi modificabili (Email e Comment).
Fare in modo che il primo BoundField visualizzi la proprietà UserName; imposta le proprietà HeaderText e DataField su "UserName". Questo campo non sarà modificabile, quindi impostarne la ReadOnly proprietà su True. Configurare il BoundField LastLoginDate impostando il suo HeaderText su "Last Login" e il suo DataField su "LastLoginDate". Formattiamo l'output di questo BoundField in modo che venga visualizzata solo la data anziché la data e l'ora. A tale scopo, impostare la proprietà di HtmlEncode BoundField su False e la relativa DataFormatString proprietà su "{0:d}". Impostare anche la ReadOnly proprietà su True.
Impostare le HeaderText proprietà dei due TemplateFields su "Email" e "Comment".
Figura 6: I campi di GridView possono essere configurati tramite la finestra di dialogo Campi (fare clic per visualizzare l'immagine a dimensione intera)
È ora necessario definire ItemTemplate e EditItemTemplate per i campi template "Email" e "Comment". Aggiungere un controllo Web Label a ciascuna delle ItemTemplates e legare le loro proprietà Text rispettivamente alle proprietà Email e Comment.
Per il TemplateField "Email", aggiungere un controllo TextBox denominato Email al suo oggetto EditItemTemplate e associare la sua proprietà Text alla proprietà Email usando il databinding bidirezionale. Aggiungere RequiredFieldValidator e RegularExpressionValidator all'oggetto EditItemTemplate per assicurarsi che un visitatore che modifica la proprietà Email abbia immesso un indirizzo di posta elettronica valido. Per il TemplateField "Commento", aggiungere un controllo TextBox a più righe denominato Comment nel suo EditItemTemplate. Impostare le proprietà Columns e Rows di TextBox rispettivamente su 40 e 4, quindi vincolare la proprietà Text alla proprietà Comment utilizzando il databinding bidirezionale.
Dopo aver configurato questi campi TemplateField, il markup dichiarativo dovrebbe essere simile al seguente:
<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>
Quando si modifica o si elimina un account utente, è necessario conoscere il valore della proprietà dell'utente UserName . Impostare la proprietà DataKeyNames del GridView su "UserName" in modo che queste informazioni siano disponibili tramite l'insieme DataKeys del GridView.
Infine, aggiungere un controllo ValidationSummary alla pagina e impostarne la ShowMessageBox proprietà su True e la relativa ShowSummary proprietà su False. Con queste impostazioni, ValidationSummary visualizzerà un avviso lato client se l'utente tenta di modificare un account utente con un indirizzo di posta elettronica mancante o non valido.
<asp:ValidationSummary ID="ValidationSummary1"
runat="server"
ShowMessageBox="True"
ShowSummary="False" />
Il markup dichiarativo di questa pagina è stato completato. L'attività successiva consiste nell'associare il set di account utente a GridView. Aggiungi un metodo chiamato BindUserGrid alla classe code-behind della pagina RoleBasedAuthorization.aspx che associa l'oggetto MembershipUserCollection restituito da Membership.GetAllUsers al UserGrid GridView. Chiamare questo metodo dal gestore eventi Page_Load alla prima visita alla pagina.
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
Con questo codice sul posto, visitare la pagina tramite un browser. Come illustrato nella figura 7, dovrebbero essere visualizzate informazioni sull'elenco GridView relative a ogni account utente nel sistema.
Figura 7: UserGrid GridView elenca le informazioni su ogni utente nel sistema (fare clic per visualizzare l'immagine a dimensione intera)
Annotazioni
Nella UserGrid GridView vengono elencati tutti gli utenti in un'interfaccia senza paginazione. Questa interfaccia griglia semplice non è adatta agli scenari in cui sono presenti diverse decine o più utenti. Un'opzione consiste nel configurare GridView per abilitare il paging. Il Membership.GetAllUsers metodo ha due overload: uno che non accetta parametri di input e restituisce tutti gli utenti e uno che accetta valori interi per l'indice di pagina e le dimensioni della pagina e restituisce solo il subset specificato degli utenti. Il secondo sovraccarico può essere utilizzato per navigare in modo più efficiente tra gli utenti, poiché restituisce solo il sottoinsieme preciso di account utente anziché tutti. Se si dispone di migliaia di account utente, è possibile prendere in considerazione un'interfaccia basata su filtro, una che mostra solo gli utenti i cui UserName iniziano con un carattere selezionato, ad esempio. Il Membership.FindUsersByName metodo è ideale per la creazione di un'interfaccia utente basata su filtro. Si esaminerà la creazione di un'interfaccia di questo tipo in un'esercitazione futura.
Il controllo GridView offre supporto predefinito per la modifica e l'eliminazione quando il controllo è associato a un controllo origine dati configurato correttamente, ad esempio SqlDataSource o ObjectDataSource.
UserGrid GridView, tuttavia, ha i dati associati a livello di codice, pertanto è necessario scrivere codice per eseguire queste due attività. In particolare, sarà necessario creare gestori eventi per gli eventi RowEditing, RowCancelingEdit, RowUpdating e RowDeleting del GridView, che vengono generati quando un visitatore fa clic sui pulsanti Edit, Cancel, Update o Delete del GridView.
Per iniziare, creare i gestori eventi per gli eventi , RowEditinge RowCancelingEdit di RowUpdatingGridView e quindi aggiungere il codice seguente:
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
I gestori eventi RowEditing e RowCancelingEdit impostano la proprietà di EditIndex GridView e quindi rilegano l'elenco di account utente alla griglia. Le cose interessanti si verificano nel RowUpdating gestore eventi. Questo gestore eventi inizia assicurandosi che i dati siano validi e quindi afferra il UserName valore dell'account utente modificato dalla DataKeys raccolta. Vengono quindi fatti riferimenti ai TextBoxes nei due TemplateFields EditItemTemplate a livello di codice. Le relative Text proprietà contengono l'indirizzo di posta elettronica e il commento modificati.
Per aggiornare un account utente tramite l'API di appartenenza, è necessario prima ottenere le informazioni dell'utente, che viene eseguita tramite una chiamata a Membership.GetUser(userName). Le proprietà Email e Comment dell'oggetto MembershipUser restituito vengono quindi aggiornate con i valori immessi nelle due caselle di testo dall'interfaccia di modifica. Infine, queste modifiche vengono salvate con una chiamata a Membership.UpdateUser. Il RowUpdating gestore eventi viene completato ripristinando GridView all'interfaccia di modifica precedente.
Creare quindi il RowDeleting gestore eventi RowDeleting e quindi aggiungere il codice seguente:
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
Il gestore eventi precedente inizia prelevando il valore UserName dalla raccolta DataKeys di GridView. Questo valore UserName viene quindi passato al metodo DeleteUser della classe Membership. Il DeleteUser metodo elimina l'account utente dal sistema, inclusi i dati di appartenenza correlati, ad esempio i ruoli a cui appartiene l'utente. Dopo l'eliminazione dell'utente, la griglia EditIndex viene impostata su -1 (nel caso in cui l'utente abbia fatto clic su Elimina mentre un'altra riga era in modalità di modifica) e viene chiamato il metodo BindUserGrid.
Annotazioni
Il pulsante Elimina non richiede alcun tipo di conferma da parte dell'utente prima di eliminare l'account utente. Ti invito ad aggiungere una forma di conferma dell'utente per ridurre la possibilità di eliminare accidentalmente un account. Uno dei modi più semplici per confermare un'azione consiste nell'usare una finestra di dialogo di conferma sul lato client. Per ulteriori informazioni su questa tecnica, vedere Aggiunta di Client-Side conferma durante l'eliminazione.
Verificare che questa pagina funzioni come previsto. Dovrebbe essere possibile modificare l'indirizzo di posta elettronica e il commento di qualsiasi utente, nonché eliminare qualsiasi account utente. Poiché la RoleBasedAuthorization.aspx pagina è accessibile a tutti gli utenti, tutti gli utenti, anche i visitatori anonimi, possono visitare questa pagina e modificare ed eliminare gli account utente. Aggiorniamo questa pagina in modo che solo gli utenti nei ruoli Supervisori e Amministratori possano modificare l'indirizzo di posta elettronica e il commento di un utente e solo gli amministratori possono eliminare un account utente.
La sezione "Uso del controllo LoginView" esamina l'uso del controllo LoginView per visualizzare istruzioni specifiche del ruolo dell'utente. Se una persona nel ruolo Amministratori visita questa pagina, mostreremo le istruzioni su come modificare ed eliminare gli utenti. Se un utente nel ruolo Supervisori raggiunge questa pagina, verranno visualizzate le istruzioni per la modifica degli utenti. E se il visitatore è anonimo o non si trova nel ruolo Supervisori o Amministratori, verrà visualizzato un messaggio che spiega che non può modificare o eliminare le informazioni sull'account utente. Nella sezione "Limitazione della funzionalità a livello di codice" si scriverà codice che a livello di codice mostra o nasconde i pulsanti Modifica ed Elimina in base al ruolo dell'utente.
Uso del controllo LoginView
Come illustrato nelle esercitazioni precedenti, il controllo LoginView è utile per visualizzare interfacce diverse per gli utenti autenticati e anonimi, ma il controllo LoginView può essere usato anche per visualizzare markup diversi in base ai ruoli dell'utente. Si userà un controllo LoginView per visualizzare istruzioni diverse in base al ruolo dell'utente in visita.
Per iniziare, aggiungi un LoginView sopra il UserGrid GridView. Come illustrato in precedenza, il controllo LoginView include due modelli predefiniti: AnonymousTemplate e LoggedInTemplate. Immettere un breve messaggio in entrambi questi modelli che informa l'utente che non può modificare o eliminare informazioni utente.
<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>
Oltre a AnonymousTemplate e LoggedInTemplate, il controllo LoginView può includere RoleGroup, ovvero modelli specifici del ruolo. Ogni RoleGroup contiene una singola proprietà, Roles, che specifica i ruoli a cui si applica RoleGroup. La Roles proprietà può essere impostata su un singolo ruolo (ad esempio "Amministratori") o su un elenco delimitato da virgole di ruoli ,ad esempio "Amministratori, Supervisori".
Per gestire i RoleGroups, fare clic sul collegamento "Modifica RoleGroups" dallo Smart Tag del controllo per visualizzare l'Editor della raccolta di RoleGroup. Aggiungere due nuovi RoleGroup. Impostare la proprietà del primo Roles RoleGroup su "Administrators" e del secondo su "Supervisors".
Figura 8: Gestisci i modelli LoginView specifico per ruolo tramite l'Editor della raccolta RoleGroup (Fare clic per visualizzare l'immagine a dimensione intera)
Fare clic OK per chiudere l'Editor della Raccolta RoleGroup; questo aggiorna il markup dichiarativo di LoginView per includere una sezione <RoleGroups> che include un elemento figlio <asp:RoleGroup> per ogni RoleGroup definito nell'Editor della Raccolta RoleGroup. Inoltre, l'elenco a discesa "Visualizzazioni" nello Smart Tag di LoginView, che inizialmente elenca solo AnonymousTemplate e LoggedInTemplate , ora include anche i RoleGroup aggiunti.
Modificare i RoleGroup in modo che gli utenti nel ruolo Supervisori vengano visualizzate istruzioni su come modificare gli account utente, mentre gli utenti nel ruolo Amministratori vengono visualizzate le istruzioni per la modifica e l'eliminazione. Dopo aver apportato queste modifiche, il markup dichiarativo di LoginView dovrebbe essere simile al seguente.
<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>
Dopo aver apportato queste modifiche, salvare la pagina e quindi visitare la pagina tramite un browser. Visitare prima di tutto la pagina come utente anonimo. Ti dovrebbe essere visualizzato il messaggio "Non sei connesso al sistema." Pertanto non è possibile modificare o eliminare informazioni sull'utente." Accedere quindi come utente autenticato, ma non è né nel ruolo Supervisori né Amministratori. Questa volta dovresti vedere il messaggio, "Non sei un membro dei ruoli Supervisori o Amministratori." Pertanto non è possibile modificare o eliminare informazioni sull'utente."
Accedere quindi come utente membro del ruolo Supervisors. Questa volta verrà visualizzato il messaggio specifico del ruolo Supervisors (vedere la figura 9). Se si accede come utente nel ruolo Amministratori, verrà visualizzato il messaggio Specifico del ruolo Administrators (vedere la figura 10).
Figura 9: A Bruce viene mostrato il messaggio specifico per il ruolo del supervisore (fare clic per visualizzare l'immagine a dimensione intera)
Figura 10: A Tito viene visualizzato il messaggio specifico per ruolo degli amministratori (fare clic per visualizzare l'immagine a dimensione intera)
Come mostrano le schermate nelle figure 9 e 10, LoginView esegue il rendering di un solo modello, anche se si applicano più modelli. Bruce e Tito sono entrambi utenti connessi, ma LoginView esegue il rendering solo del RoleGroup corrispondente e non di LoggedInTemplate. Inoltre, Tito appartiene sia ai ruoli Administrators che Supervisors, ma il controllo LoginView esegue il rendering del modello specifico del ruolo Administrators anziché quello dei supervisori.
Nella figura 11 viene illustrato il flusso di lavoro usato dal controllo LoginView per determinare il modello di cui eseguire il rendering. Si noti che se sono presenti più di un RoleGroup specificato, il modello LoginView esegue il rendering del primo RoleGroup corrispondente. In altre parole, se avessimo inserito il Gruppo di ruoli supervisori come primo RoleGroup e gli amministratori come secondo, quando Tito ha visitato questa pagina, visualizzerebbe il messaggio Supervisori.
Figura 11: Flusso di lavoro del controllo LoginView per determinare il modello di rendering (fare clic per visualizzare l'immagine a dimensione intera)
Limitazione delle funzionalità a livello di codice
Mentre il controllo LoginView visualizza istruzioni diverse in base al ruolo dell'utente che visita la pagina, i pulsanti Modifica e Annulla rimangono visibili a tutti. È necessario nascondere a livello di codice i pulsanti Modifica ed Elimina per i visitatori anonimi e gli utenti che non si trovano né nel ruolo Supervisori né Amministratori. È necessario nascondere il pulsante Elimina per tutti gli utenti che non sono amministratori. A tale scopo, si scriverà un po' di codice che fa riferimento a livello di codice ai pulsanti Edit e Delete LinkButton di CommandField e ne imposta Visible le proprietà su False, se necessario.
Il modo più semplice per fare riferimento a controlli a livello di codice in un oggetto CommandField consiste nel convertirlo in un modello. A tale scopo, fare clic sul collegamento "Modifica colonne" dallo Smart Tag di GridView, selezionare Il campo di comando dall'elenco dei campi correnti e fare clic sul collegamento "Converti questo campo in un campo modello". In questo modo, CommandField viene trasformato in un oggetto TemplateField con un ItemTemplate e un EditItemTemplate.
ItemTemplate Contiene i pulsanti Di modifica ed eliminazione di link mentre ospita EditItemTemplate i pulsanti Update e Cancel LinkButtons.
Figura 12: Convertire il campo di comando in un campo modello (fare clic per visualizzare l'immagine a dimensione intera)
Aggiornare i pulsanti di collegamento Edit e Delete in ItemTemplate, impostando le loro proprietà su ID rispettivamente ai valori di EditButton e DeleteButton.
<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>
Ogni volta che i dati vengono associati a GridView, GridView enumera i record nella relativa DataSource proprietà e genera un oggetto corrispondente GridViewRow . Quando viene creato ogni GridViewRow oggetto, viene generato l'evento RowCreated . Per nascondere i pulsanti Modifica ed Elimina per utenti non autorizzati, è necessario creare un gestore eventi per questo evento e fare riferimento a livello di codice ai pulsanti Edit e Delete LinkButtons, impostandone Visible le proprietà di conseguenza.
Creare un gestore eventi per l'evento RowCreated e quindi aggiungere il codice seguente:
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
Tenere presente che l'evento RowCreated viene generato per tutte le righe GridView, tra cui l'intestazione, il piè di pagina, l'interfaccia del paginatore e così via. Si vuole fare riferimento a livello di codice ai pulsanti Modifica ed Elimina link solo se si tratta di una riga di dati non in modalità di modifica (poiché la riga in modalità di modifica ha pulsanti Aggiorna e Annulla anziché Modifica ed Elimina). Questo controllo viene gestito dall'istruzione If .
Se stiamo gestendo una riga di dati che non è in modalità di modifica, vengono fatti riferimento ai pulsanti Modifica ed Elimina e le relative Visible proprietà vengono impostate in base ai valori booleani restituiti dal metodo dell'oggetto UserIsInRole(roleName). L'oggetto User fa riferimento al principal creato da RoleManagerModule; di conseguenza, il metodo IsInRole(roleName) utilizza l'API Roles per determinare se il visitatore corrente appartiene a roleName.
Annotazioni
È possibile usare direttamente la classe Roles, sostituendo la chiamata a User.IsInRole(roleName) con una chiamata al Roles.IsUserInRole(roleName) metodo . Ho deciso di usare il metodo dell'oggetto IsInRole(roleName) principale in questo esempio perché è più efficiente rispetto all'utilizzo diretto dell'API Roles. In precedenza in questa esercitazione è stato configurato il gestore dei ruoli per memorizzare nella cache i ruoli dell'utente in un cookie. Questi dati dei cookie memorizzati nella cache vengono utilizzati solo quando viene chiamato il metodo dell'entità IsInRole(roleName); le chiamate dirette alla Roles API comportano sempre un accesso allo store dei ruoli. Anche se i ruoli non vengono memorizzati nella cache in un cookie, la chiamata al metodo dell'oggetto IsInRole(roleName) principale è in genere più efficiente perché quando viene chiamato per la prima volta durante una richiesta memorizza nella cache i risultati. L'API Ruoli, d'altra parte, non esegue alcuna memorizzazione nella cache. Poiché l'evento RowCreated viene generato una volta per ogni riga in GridView, l'uso User.IsInRole(roleName) prevede solo un viaggio nell'archivio ruoli, mentre Roles.IsUserInRole(roleName) richiede N corse, dove N è il numero di account utente visualizzati nella griglia.
La proprietà del Visible pulsante Modifica è impostata su True se l'utente che visita questa pagina si trova nel ruolo Amministratori o Supervisori; in caso contrario, è impostato su False. La proprietà del Visible pulsante Elimina è impostata su True solo se l'utente è nel ruolo Administrators.
Testare questa pagina tramite un browser. Se si visita la pagina come visitatore anonimo o come utente che non è né un supervisore né un amministratore, CommandField è vuoto; esiste ancora, ma come un sottile sliver senza i pulsanti Modifica o Elimina.
Annotazioni
È possibile nascondere completamente il campo di comando quando un non supervisore e non amministratore sta visitando la pagina. Lascio questo come esercizio per il lettore.
Figura 13: I pulsanti modifica ed eliminazione sono nascosti per i non supervisori e gli amministratori non (fare clic per visualizzare l'immagine a dimensione intera)
Se un utente che appartiene al ruolo Supervisori (ma non al ruolo Amministratori), visualizza solo il pulsante Modifica.
Figura 14: Mentre il pulsante Modifica è disponibile per i supervisori, il pulsante Elimina è nascosto (fare clic per visualizzare l'immagine a dimensione intera)
E se un amministratore visita, ha accesso ai pulsanti Modifica ed Elimina.
Figura 15: I pulsanti Modifica ed Elimina sono disponibili solo per gli amministratori (fare clic per visualizzare l'immagine a dimensione intera)
Passaggio 3: Applicazione di regole di autorizzazione basate sui ruoli a classi e metodi
Nel passaggio 2 sono state limitate le funzionalità di modifica agli utenti nei ruoli Supervisori e Amministratori ed è possibile eliminare solo le funzionalità per gli amministratori. Questa operazione è stata eseguita nascondendo gli elementi dell'interfaccia utente associati per utenti non autorizzati tramite tecniche a livello di codice. Tali misure non garantiscono che un utente non autorizzato non sia in grado di eseguire un'azione con privilegi. Potrebbero essere presenti elementi dell'interfaccia utente aggiunti in un secondo momento o che si è dimenticato di nascondersi per gli utenti non autorizzati. Oppure un hacker potrebbe scoprire un altro modo per ottenere la pagina ASP.NET per eseguire il metodo desiderato.
Un modo semplice per garantire che non sia possibile accedere a una determinata parte di funzionalità da parte di un utente non autorizzato consiste nel decorare tale classe o metodo con l'attributoPrincipalPermission . Quando il runtime .NET usa una classe o esegue uno dei relativi metodi, verifica che il contesto di sicurezza corrente disponga dell'autorizzazione. L'attributo PrincipalPermission fornisce un meccanismo tramite il quale è possibile definire queste regole.
Abbiamo esaminato l'uso dell'attributo nell'esercitazione di autorizzazione basata sull'utente. In particolare, abbiamo visto come decorare gli handler di evento SelectedIndexChanged e RowDeleting di GridView, in modo che possano essere eseguiti solo da utenti autenticati e da Tito, rispettivamente. L'attributo PrincipalPermission funziona anche con i ruoli.
Di seguito viene illustrato l'uso dell'attributo PrincipalPermission nei gestori eventi e RowUpdating di RowDeleting GridView per impedire l'esecuzione per gli utenti non autorizzati. È sufficiente aggiungere l'attributo appropriato in cima a ogni definizione di funzione:
<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'attributo per il RowUpdating gestore eventi determina che solo gli utenti nei ruoli Administrators o Supervisors possono eseguire il gestore eventi, dove come attributo nel RowDeleting gestore eventi limita l'esecuzione agli utenti nel ruolo Administrators.
Annotazioni
L'attributo PrincipalPermission è rappresentato come classe nello spazio dei nomi System.Security.Permissions. Assicurarsi di aggiungere un'istruzione Imports System.Security.Permissions all'inizio del file di classe code-behind per importare il namespace.
Se, in qualche modo, un non-Amministratore tenta di eseguire il gestore eventi RowDeleting o se un non-Supervisore o un non-Amministratore tenta di eseguire il gestore eventi RowUpdating, il runtime .NET genererà un'eccezione SecurityException.
Figura 16: Se il contesto di sicurezza non è autorizzato a eseguire il metodo, viene generata un'eccezione SecurityException (fare clic per visualizzare l'immagine a dimensione intera)
Oltre a ASP.NET pagine, molte applicazioni hanno anche un'architettura che include vari livelli, ad esempio logica di business e livelli di accesso ai dati. Questi livelli vengono in genere implementati come librerie di classi e offrono classi e metodi per l'esecuzione di logica di business e funzionalità correlate ai dati. L'attributo è utile anche per l'applicazione PrincipalPermission di regole di autorizzazione a questi livelli.
Per altre informazioni sull'uso dell'attributo PrincipalPermission per definire regole di autorizzazione per classi e metodi, vedere il post del blog di Scott GuthrieAggiunta di regole di autorizzazione ai livelli business e di dati tramite PrincipalPermissionAttributes.
Sommario
In questa esercitazione è stato illustrato come specificare regole di autorizzazione grossolane e granulari in base ai ruoli dell'utente. La funzionalità di autorizzazione URL di ASP.NET consente a un sviluppatore di applicazioni web di specificare quali identità possono accedere o sono negate l'accesso a determinate pagine. Come abbiamo visto nel tutorial sull'autorizzazione basata su utente, le regole di autorizzazione URL possono essere applicate per singolo utente. Possono anche essere applicati in base al ruolo, come illustrato nel passaggio 1 di questa esercitazione.
Le regole di autorizzazione con granularità fine possono essere applicate in modo dichiarativo o a livello di codice. Nel passaggio 2 è stato esaminato l'uso della funzionalità RoleGroups del controllo LoginView per eseguire il rendering di output diversi in base ai ruoli dell'utente in visita. Sono stati inoltre esaminati i modi per determinare a livello di codice se un utente appartiene a un ruolo specifico e come modificare di conseguenza le funzionalità della pagina.
Buon programmatori!
Altre informazioni
Per altre informazioni sugli argomenti illustrati in questa esercitazione, vedere le risorse seguenti:
-
Aggiunta di regole di autorizzazione ai livelli aziendale e dei dati tramite
PrincipalPermissionAttributes - Esame dell'appartenenza, dei ruoli e del profilo di ASP.NET 2.0: Utilizzo dei ruoli
- Elenco delle domande di sicurezza per ASP.NET 2.0
-
Documentazione tecnica per l'elemento
<roleManager>
Informazioni sull'autore
Scott Mitchell, autore di più libri ASP/ASP.NET e fondatore di 4GuysFromRolla.com, ha lavorato con le tecnologie Web Microsoft dal 1998. Scott lavora come consulente indipendente, formatore e scrittore. Il suo ultimo libro è Sams Teach Yourself ASP.NET 2.0 in 24 ore. Scott può essere raggiunto a mitchell@4guysfromrolla.com o tramite il suo blog all'indirizzo http://ScottOnWriting.NET.
Grazie speciali a...
Questa serie di esercitazioni è stata esaminata da molti revisori competenti. I principali revisori per questa esercitazione includono Suchi Banerjee e Teresa Murphy. Si è interessati a esaminare i prossimi articoli MSDN? In tal caso, mandami un messaggio a mitchell@4GuysFromRolla.com