Condividi tramite


Autorizzazione basata sui ruoli (C#)

di Scott Mitchell

Nota

Poiché questo articolo è stato scritto, i provider di appartenenza ASP.NET sono stati sostituiti da ASP.NET Identity. È consigliabile aggiornare le app per usare la ASP.NET Identity Platform anziché i provider di appartenenza in primo piano al momento della scrittura di questo articolo. ASP.NET Identity offre numerosi vantaggi rispetto al sistema di appartenenza ASP.NET, tra cui :

  • Prestazioni migliori
  • Miglioramento dell'estendibilità e della testability
  • Supporto per OAuth, OpenID Connect e autenticazione a due fattori
  • Supporto delle identità basate sulle attestazioni
  • Interoperabilità migliore 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 le regole di autorizzazione dell'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 basata sull'utente è 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 per consentire solo agli utenti autenticati di visitare una pagina. O potremmo determinare che solo gli utenti Tito e Bob sono stati consentiti o indicano che tutti gli utenti autenticati tranne Sam erano 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 possono visualizzare il contenuto dei file e solo Tito potrebbe eliminare i file.

L'applicazione delle regole di autorizzazione su base utente può crescere in un incubo di contabilità. Un approccio più gestibile consiste nell'usare l'autorizzazione basata su ruoli. La buona notizia è che gli strumenti a disposizione per applicare le 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 contenuti diversi in base ai ruoli dell'utente registrati. L'API Ruoli include metodi per determinare i ruoli dell'utente registrati.

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 le regole di autorizzazione dell'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. È possibile iniziare subito.

Informazioni su come i ruoli sono associati al contesto di sicurezza di un utente

Ogni volta che una richiesta immette la pipeline di ASP.NET associata a un contesto di sicurezza, che include informazioni che identificano il richiedente. Quando si usa l'autenticazione dei moduli, viene usato un ticket di autenticazione come token di identità. Come illustrato nell'esercitazione Panoramica dell'autenticazione dei moduli, l'oggetto FormsAuthenticationModule è responsabile della determinazione dell'identità del richiedente, che esegue durante l'eventoAuthenticateRequest.

Se viene trovato un ticket di autenticazione valido e non scaduto, lo FormsAuthenticationModule decodifica per verificare l'identità del richiedente. Crea un nuovo GenericPrincipal oggetto e lo assegna all'oggetto HttpContext.User . Lo scopo di un'entità, ad esempio GenericPrincipal, è identificare il nome dell'utente autenticato e i ruoli a cui appartiene. Questo scopo è evidente dal fatto che tutti gli oggetti principali hanno una proprietà e un IdentityIsInRole(roleName) metodo. Tuttavia FormsAuthenticationModule, non è interessato alla registrazione delle informazioni sul ruolo e l'oggetto GenericPrincipal creato non specifica alcun ruolo.

Se il framework Ruoli è abilitato, il RoleManagerModule modulo HTTP viene eseguito dopo FormsAuthenticationModule e identifica i ruoli dell'utente autenticati durante l'eventoPostAuthenticateRequest, che viene generato dopo l'eventoAuthenticateRequest. Se la richiesta proviene da un utente autenticato, l'oggetto RoleManagerModule sovrascrive l'oggetto GenericPrincipal creato dall'oggetto FormsAuthenticationModule e lo sostituisce con un RolePrincipal oggetto. La RolePrincipal classe usa l'API Ruoli 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 dei moduli e il framework Ruoli. L'oggetto FormsAuthenticationModule esegue prima, identifica l'utente tramite il ticket di autenticazione e crea un nuovo GenericPrincipal oggetto. Successivamente, i RoleManagerModule passaggi in e sovrascrivono l'oggetto GenericPrincipal con un RolePrincipal oggetto.

Se un utente anonimo visita il sito, né l'oggetto FormsAuthenticationModule né crea RoleManagerModule un oggetto principale.

Eventi della pipeline ASP.NET per un utente autenticato quando si usa l'autenticazione dei moduli e il framework ruoli

Figura 1: Gli eventi della pipeline ASP.NET per un utente autenticato quando usano l'autenticazione dei moduli e il framework ruoli (fare clic per visualizzare l'immagine full-size)

Il RolePrincipal metodo dell'oggetto IsInRole(roleName) chiama Roles.GetRolesForUser per ottenere i ruoli per l'utente per determinare se l'utente è un membro di roleName. Quando si usa , questo comporta una query nel database dell'archivio SqlRoleProviderruoli. Quando si usano regole di autorizzazione url basate su ruoli, il RolePrincipalmetodo 's verrà chiamato su ogni richiesta a una pagina protetta dalle regole di IsInRole autorizzazione dell'URL basate sul ruolo. Anziché cercare le informazioni sul ruolo nel database in ogni richiesta, il framework Ruoli 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 cookie viene creato durante l'evento della EndRequestpipeline di 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, salvando così l'oggetto da dover effettuare una chiamata alla Roles classe per determinare i RolePrincipal ruoli dell'utente. La figura 2 illustra questo flusso di lavoro.

Le informazioni sul ruolo dell'utente possono essere archiviate in un cookie per migliorare le prestazioni

Figura 2: le informazioni sul ruolo dell'utente possono essere archiviate in un cookie per migliorare le prestazioni (fare clic per visualizzare l'immagine full-size)

Per impostazione predefinita, il meccanismo di cookie della cache dei ruoli è disabilitato. Può essere abilitato tramite il markup di <roleManager> configurazione in Web.config. È stato illustrato l'uso dell'elemento<roleManager> per specificare i provider di ruoli nell'esercitazione Creazione e gestione dei ruoli, pertanto è necessario avere già questo elemento nel file dell'applicazioneWeb.config. Le impostazioni del cookie della cache dei ruoli vengono specificate come attributi dell'elemento <roleManager> e vengono riepilogate nella tabella 1.

Nota

Le impostazioni di configurazione elencate nella tabella 1 specificano le proprietà del cookie della cache dei ruoli risultante. Per altre informazioni sui cookie, sul funzionamento e sulle relative varie proprietà, leggere questa esercitazione sui cookie.

Proprietà Descrizione
cacheRolesInCookie Valore booleano che indica se viene usata la memorizzazione nella cache dei cookie. Il valore predefinito è false.
cookieName Nome del cookie della cache dei ruoli. 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; Nonee Validation.
cookieRequireSSL Valore booleano che indica se è necessaria una connessione SSL per trasmettere il cookie di autenticazione. Il valore predefinito è false.
cookieSlidingExpiration Valore booleano che indica se il timeout del cookie viene reimpostato ogni volta che l'utente visita il sito durante una singola sessione. Il valore predefinito è false. Questo valore è pertinente solo quando createPersistentCookie è impostato su true.
cookieTimeout Specifica l'ora, in minuti, dopo la quale il cookie del ticket di autenticazione scade. Il valore predefinito è 30. Questo valore è pertinente solo quando createPersistentCookie è impostato su true.
createPersistentCookie Valore booleano che specifica se il cookie della cache dei ruoli è un cookie di sessione o un cookie persistente. Se false (impostazione predefinita), viene usato un cookie di sessione, che viene eliminato quando il browser viene chiuso. Se trueviene usato un cookie persistente; scade cookieTimeout il numero di minuti dopo la creazione o dopo la visita precedente, a seconda del valore di cookieSlidingExpiration.
domain Specifica il valore di dominio del cookie. Il valore predefinito è una stringa vuota, che fa sì che il browser usi il dominio da cui è stato rilasciato (ad esempio www.yourdomain.com). In questo caso, il cookie non verrà inviato quando si effettuano richieste ai sottodomini, ad esempio admin.yourdomain.com. Se si vuole che il cookie venga passato a tutti i sottodomini, è necessario personalizzare l'attributo domain , impostandolo su "yourdomain.com".
maxCachedResults Specifica il numero massimo di nomi di ruolo memorizzati nella cache nel cookie. Il valore predefinito è 25. Non RoleManagerModule crea un cookie per gli utenti che appartengono a più maxCachedResults ruoli. Di conseguenza, il RolePrincipal metodo dell'oggetto IsInRole userà la Roles classe per determinare i ruoli dell'utente. Il motivo maxCachedResults è che molti agenti utente non consentono cookie superiori a 4.096 byte. Questo limite è quindi destinato a ridurre la probabilità di superare questa limitazione delle dimensioni. Se si hanno nomi di ruolo estremamente lunghi, è possibile valutare la possibilità di specificare un valore più maxCachedResults piccolo; in caso contrario, se si hanno nomi di ruolo estremamente brevi, è probabilmente possibile aumentare questo valore.

Tabella 1: Opzioni di configurazione del cookie della cache dei ruoli

Configurare l'applicazione per l'uso dei cookie della cache dei ruoli non persistenti. A questo 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>

L'elemento <roleManager> è stato aggiornato 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. È possibile impostare in modo esplicito gli createPersistentCookie attributi e su false e cookieProtectionAll, rispettivamente. Tecnicamente, non ho dovuto specificare i valori per questi attributi perché li ho appena assegnati ai valori predefiniti, ma li ho messi qui per renderli chiari in modo esplicito che non usi cookie persistenti e che il cookie sia crittografato e convalidato.

Questo è tutto ciò che occorre fare. Di conseguenza, il framework Ruoli memorizza 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 è importante, l'oggetto RolePrincipal userà semplicemente la Roles classe nel caso in cui non sia disponibile alcun cookie (o un cookie non valido o scaduto).

Nota

Il gruppo Modelli di Microsoft & Practices sconsiglia l'uso dei cookie della cache dei ruoli persistenti. Poiché il possesso del cookie della cache dei ruoli è sufficiente per dimostrare l'appartenenza al ruolo, se un hacker può in qualche modo ottenere l'accesso ai cookie di un utente valido che può rappresentare tale utente. La probabilità che ciò si verifichi aumenta se il cookie viene mantenuto nel browser dell'utente. Per altre informazioni su questa raccomandazione sulla sicurezza, nonché su altre problematiche di sicurezza, vedere l'elenco domande di sicurezza per ASP.NET 2.0.

Passaggio 1: Definizione delle regole di autorizzazione dell'URL Role-Based

Come illustrato nell'esercitazione Sull'autorizzazione basata sull'utente, l'autorizzazione dell'URL offre un mezzo per limitare l'accesso a un set di pagine in base all'utente o al ruolo. Le regole di autorizzazione DELL'URL vengono compilate usando Web.configl'elemento<authorization> con <allow> e <deny> gli elementi figlio. Oltre alle regole di autorizzazione correlate all'utente descritte nelle esercitazioni precedenti, ogni <allow> elemento e <deny> figlio può includere anche:

  • Un ruolo specifico
  • Elenco delimitato da virgole dei ruoli

Ad esempio, le regole di autorizzazione URL consentono 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 nel markup precedente indica che i ruoli Administrators e Supervisors sono consentiti. <deny> L'elemento <allow> indica che tutti gli utenti vengono negati.

Configurare l'applicazione in modo che le ManageRoles.aspxpagine , UsersAndRoles.aspxe CreateUserWizardWithRoles.aspx siano accessibili solo a tali 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.

Aggiungere un file di Web.config alla directory Ruoli

Figura 3: Aggiungere un file alla directory (fare clic per visualizzare l'immagineWeb.configRoles full-size)

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 di 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. Verrà UrlAuthorizationModule rilevato che non si dispone dell'autorizzazione per visitare la risorsa richiesta. Di conseguenza, l'utente FormsAuthenticationModule verrà reindirizzato alla pagina di accesso. La pagina di accesso reindirizzerà quindi alla UnauthorizedAccess.aspx pagina (vedere la figura 4). Questo reindirizzamento finale dalla pagina di accesso a UnauthorizedAccess.aspx si verifica a causa del codice aggiunto alla pagina di accesso nel passaggio 2 dell'esercitazione Sull'autorizzazione basata sull'utente . In particolare, la pagina di accesso reindirizza automaticamente qualsiasi utente autenticato a UnauthorizedAccess.aspx se la querystring 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 è stata autorizzata a visualizzare.

Solo gli utenti nel ruolo Amministratori possono visualizzare le pagine protette

Figura 4: solo gli utenti nel ruolo Amministratori possono visualizzare le pagine protette (fare clic per visualizzare l'immagine full-size)

Disconnettersi e quindi accedere come utente che si trova nel ruolo Administrators. Ora si dovrebbe essere in grado di visualizzare le tre pagine protette.

Tito può visitare la pagina UsersAndRoles.aspx Perché si trova nel ruolo Amministratori

Figura 5: Tito può visitare la pagina Perché è nel ruolo amministratori (fare clic per visualizzare l'immagineUsersAndRoles.aspx a dimensioni complete)

Nota

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, l'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, l'utente ha concesso l'accesso. Di conseguenza, se si vuole limitare l'accesso a uno o più account utente, è imperativo usare un <deny> elemento come ultimo elemento nella configurazione dell'autorizzazione URL. Se le regole di autorizzazione dell'URL non includono un<deny>elemento, tutti gli utenti potranno accedere. Per una discussione più approfondita sul modo in cui vengono analizzate le regole di autorizzazione url, fare riferimento alla sezione "A Look at How the Uses the Authorization Rules to Grant or Deny Access" (Informazioni su come UrlAuthorizationModule usare le regole di autorizzazione per concedere o negare l'accesso) dell'esercitazione sull'autorizzazione basata sull'utente .

Passaggio 2: Limitazione delle funzionalità in base ai ruoli dell'utente attualmente connessi

L'autorizzazione URL consente di specificare regole di autorizzazione grossolane che indicano quali identità sono consentite e quali sono negate dalla visualizzazione di una determinata pagina (o di tutte le pagine in una cartella e nelle relative sottocartelle). Tuttavia, in alcuni casi è possibile consentire a tutti gli utenti di visitare una pagina, ma limitare la funzionalità della pagina in base ai ruoli dell'utente in visita. Ciò può comportare la visualizzazione o la nascondere dei dati in base al ruolo dell'utente o offrire funzionalità aggiuntive agli utenti che appartengono a un determinato ruolo.

Tali regole di autorizzazione basate su ruoli granulari 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. Di seguito verranno esaminate le tecniche a livello di codice. Prima di poter esaminare l'applicazione di regole di autorizzazione di granularità fine, è tuttavia prima necessario creare una pagina la cui funzionalità dipende dal ruolo dell'utente che lo visita.

Verrà 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, l'ultima data di accesso e i commenti sull'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 "Uso del controllo LoginView" e "Limitazione a livello di codice" verrà illustrato come abilitare o disabilitare queste funzionalità in base al ruolo dell'utente in visita.

Nota

La pagina ASP.NET che si sta per compilare usa un controllo GridView per visualizzare gli account utente. Poiché questa serie di esercitazioni si concentra sull'autenticazione dei moduli, l'autorizzazione, gli account utente e i ruoli, non si vuole 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 descrive i dettagli del motivo per cui sono state effettuate determinate scelte o quali effetti hanno sull'output sottoposto a rendering. Per un esame approfondito del controllo GridView, vedere Uso dei dati in ASP.NET serie di esercitazioni 2.0.

Iniziare aprendo la RoleBasedAuthorization.aspx pagina nella Roles cartella. Trascinare gridView dalla pagina nell'Designer e impostarne su IDUserGrid. In un momento verrà scritto codice che chiama il metodo e associa l'oggetto Membership.GetAllUsers risultante MembershipUserCollection a GridView. Contiene un MembershipUser oggetto per ogni account utente nel sistema. MembershipUser Gli MembershipUserCollection oggetti hanno proprietà come UserName, Email, LastLoginDatee così via.

Prima di scrivere il codice che associa gli account utente alla griglia, definire prima i campi di GridView. Dal smart tag di GridView fare clic sul collegamento "Modifica colonne" per avviare la finestra di dialogo Campi (vedere Figura 6). Da qui deselezionare la casella di controllo "Genera automaticamente campi" nell'angolo inferiore sinistro. Poiché si vuole che GridView includa la modifica e l'eliminazione di funzionalità, aggiungere un CommandField e impostare le ShowEditButton relative proprietà e ShowDeleteButton su True. Aggiungere quindi quattro campi per visualizzare le UserNameproprietà , , LastLoginDateEmaile Comment . Usare un oggetto BoundField per le due proprietà di sola lettura (UserName e LastLoginDate) e TemplateFields per i due campi modificabili (Email e Comment).

Visualizzare la UserName prima proprietà BoundField; impostarne HeaderText le proprietà e DataField su "UserName". Questo campo non sarà modificabile, quindi impostare la relativa ReadOnly proprietà su True. Configurare BoundField LastLoginDate impostando HeaderText su "Last Login" e su DataField "LastLoginDate". Formattare l'output di questo BoundField in modo che venga visualizzata solo la data anziché la data e l'ora. A questo scopo, impostare la proprietà BoundField HtmlEncode 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".

I campi di GridView possono essere configurati tramite la finestra di dialogo Campi

Figura 6: I campi di GridView possono essere configurati tramite la finestra di dialogo Campi (fare clic per visualizzare l'immagine a dimensioni complete)

È ora necessario definire e ItemTemplateEditItemTemplate per i modelli "Email" e "Commento". Aggiungere rispettivamente un controllo Web Label a ognuno degli ItemTemplate s e associare le relative Text proprietà alle Email proprietà e Comment .

Per il modello "Email" TemplateField, aggiungere un oggetto TextBox denominato Email al relativo EditItemTemplate e associarne la TextEmail proprietà alla proprietà usando il databinding bidirezionale. Aggiungere un oggetto RequiredFieldValidator e RegularExpressionValidator per EditItemTemplate assicurarsi che un visitatore che modifica la proprietà Email abbia immesso un indirizzo di posta elettronica valido. Per il modello "Comment" TemplateField, aggiungere una casella di testo a più righe denominata Comment al relativo EditItemTemplateoggetto . Impostare rispettivamente le proprietà e Rows e di TextBox Columns su 40 e 4 e quindi associare la Comment proprietà Text alla proprietà usando la combinazione di dati bidirezionale.

Dopo aver configurato questi campi modello, 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à GridView su "UserName" in modo che queste informazioni siano disponibili tramite l'insieme DataKeys GridViewDataKeyNames.

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" />

È stato completato il markup dichiarativo di questa pagina. L'attività successiva consiste nel associare il set di account utente a GridView. Aggiungere un metodo denominato BindUserGrid alla RoleBasedAuthorization.aspx classe code-behind della pagina che associa l'oggetto MembershipUserCollection restituito da Membership.GetAllUsers GridView UserGrid . Chiamare questo metodo dal Page_Load gestore eventi nella prima pagina visita.

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

private void BindUserGrid()    
{    
     MembershipUserCollection allUsers = Membership.GetAllUsers();    
     UserGrid.DataSource = allUsers;    
     UserGrid.DataBind();    
}

Con questo codice sul posto, visitare la pagina tramite un browser. Come illustrato nella figura 7, è consigliabile visualizzare informazioni sulla presentazione di GridView su ogni account utente nel sistema.

UserGrid GridView elenca informazioni su ogni utente nel sistema

Figura 7: UserGrid GridView elenca le informazioni su ogni utente nel sistema (fare clic per visualizzare l'immagine a dimensioni complete)

Nota

UserGrid GridView elenca tutti gli utenti in un'interfaccia non a pagina. Questa semplice interfaccia della griglia 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 overload può essere usato per paginare in modo più efficiente gli utenti perché restituisce solo il subset preciso di account utente anziché tutti. Se sono presenti migliaia di account utente, potrebbe essere consigliabile considerare un'interfaccia basata su filtro, una che mostra solo gli utenti i cui Nomeutente inizia con un carattere selezionato, ad esempio. È Membership.FindUsersByName method ideale per la creazione di un'interfaccia utente basata su filtri. Verrà esaminata la creazione di un'interfaccia simile in un'esercitazione futura.

Il controllo GridView offre supporto predefinito per la modifica ed l'eliminazione quando il controllo è associato a un controllo origine dati configurato correttamente, ad esempio SqlDataSource o ObjectDataSource. UserGrid GridView, tuttavia, ha il relativo limite a livello di codice. Pertanto, è necessario scrivere codice per eseguire queste due attività. In particolare, sarà necessario creare gestori eventi per i pulsanti Edit, RowCancelingEditRowUpdatingRowDeleting Update o Delete di RowEditingGridView, che vengono attivati quando un visitatore fa clic sui pulsanti Modifica, Annulla, Aggiorna o Elimina di GridView.

Iniziare creando i gestori eventi per gli eventi , e RowCancelingEditRowUpdating di GridView RowEditinge quindi aggiungere il codice seguente:

protected void UserGrid_RowEditing(object sender, GridViewEditEventArgs e)
{
     // Set the grid's EditIndex and rebind the data

     UserGrid.EditIndex = e.NewEditIndex;
     BindUserGrid();
}

protected void UserGrid_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
{
     // Revert the grid's EditIndex to -1 and rebind the data
     UserGrid.EditIndex = -1;
     BindUserGrid();
}

protected void UserGrid_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
     // Exit if the page is not valid
     if (!Page.IsValid)
          return;

     // Determine the username of the user we are editing
     string UserName = UserGrid.DataKeys[e.RowIndex].Value.ToString();

     // Read in the entered information and update the user
     TextBox EmailTextBox = UserGrid.Rows[e.RowIndex].FindControl("Email") as TextBox;
     TextBox CommentTextBox = UserGrid.Rows[e.RowIndex].FindControl("Comment") as TextBox;

     // Return information about the user
     MembershipUser UserInfo = 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();
}

I RowEditing gestori di eventi e RowCancelingEdit impostano semplicemente la proprietà di EditIndex GridView e quindi ribinò l'elenco di account utente sulla griglia. Le cose interessanti si verifica nel RowUpdating gestore eventi. Questo gestore eventi inizia assicurandosi che i dati siano validi e quindi recupera il UserName valore dell'account DataKeys utente modificato dalla raccolta. Le Email caselle di testo e Comment nei due TemplateFields EditItemTemplate vengono quindi a cui viene fatto riferimento a livello di codice. Le proprietà Text contengono l'indirizzo e-mail modificato e il commento.

Per aggiornare un account utente tramite l'API Di appartenenza, è necessario prima ottenere le informazioni dell'utente, che vengono eseguite tramite una chiamata a Membership.GetUser(userName). Le proprietà e Comment degli oggetti Email restituiti MembershipUser 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 nell'interfaccia di pre-modifica.

Creare quindi il RowDeleting gestore eventi e quindi aggiungere il codice seguente:

protected void UserGrid_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
     // Determine the username of the user we are editing
     string UserName = 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();
}

Il gestore eventi precedente inizia afferrando il UserName valore dall'insieme DeleteUserGridViewDataKeys. Questo UserName valore viene quindi passato al metodo 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 aver eliminato l'utente, la griglia EditIndex è impostata su -1 (nel caso in cui l'utente ha fatto clic su Elimina mentre un'altra riga era in modalità di modifica) e viene chiamato il BindUserGrid metodo.

Nota

Il pulsante Elimina non richiede alcuna conferma dall'utente prima di eliminare l'account utente. Ti consigliamo di 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 è tramite una finestra di dialogo di conferma lato client. Per altre informazioni su questa tecnica, vedere Aggiunta di Client-Side conferma durante l'eliminazione.

Verificare che questa pagina funzioni come previsto. È consigliabile 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. Aggiornare 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, verranno visualizzate istruzioni su come modificare ed eliminare gli utenti. Se un utente nel ruolo Supervisori raggiunge questa pagina, verranno visualizzate le istruzioni per modificare gli utenti. Se il visitatore è anonimo o non si trova nel ruolo Supervisori o Amministratori, verrà visualizzato un messaggio che spiega che non possono modificare o eliminare le informazioni sull'account utente. Nella sezione "Limitazione a livello di codice" si scriverà codice che mostra o nasconde i pulsanti Modifica ed Eliminazione a livello di codice 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 diverso in base ai ruoli dell'utente. Si userà un controllo LoginView per visualizzare istruzioni diverse in base al ruolo dell'utente in visita.

Iniziare aggiungendo un loginView sopra 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 possono 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, che sono modelli specifici del ruolo. Ogni RoleGroup contiene una singola proprietà, , Rolesche specifica i ruoli a cui si applica RoleGroup. La Roles proprietà può essere impostata su un singolo ruolo (ad esempio "Administrators") o su un elenco delimitato da virgole di ruoli (ad esempio "Administrators, Supervisors").

Per gestire i RoleGroup, fare clic sul collegamento "Modifica ruoliGroup" dallo Smart Tag del controllo per visualizzare l'editor di raccolta RoleGroup. Aggiungere due nuovi RoleGroup. Impostare la prima proprietà roleGroup Roles su "Administrators" e su "Supervisori".

Gestire i modelli di Role-Specific di LoginView tramite l'editor raccolta RoleGroup

Figura 8: Gestire i modelli di Role-Specific di LoginView tramite l'editor raccolta RoleGroup (fare clic per visualizzare l'immagine a dimensioni complete)

Fare clic su OK per chiudere l'editor raccolta RoleGroup; questo aggiorna il markup dichiarativo di LoginView per includere una sezione con un <RoleGroups><asp:RoleGroup> elemento figlio per ogni RoleGroup definito nell'editor raccolta RoleGroup. Inoltre, l'elenco a discesa "Views" nella smart tag di LoginView, che inizialmente è elencato AnonymousTemplateLoggedInTemplate solo e 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&#39; Email and Comment information. 
                    Simply click the Edit button, make your changes, and then click Update.
               </ContentTemplate>
          </asp:RoleGroup>
     </RoleGroups>

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

Dopo aver apportato queste modifiche, salvare la pagina e quindi visitarla tramite un browser. Visitare prima di tutto la pagina come utente anonimo. Verrà visualizzato il messaggio "Non si è connessi al sistema. Pertanto non è possibile modificare o eliminare informazioni utente." Accedere quindi come utente autenticato, ma uno che non è né nei supervisori né nel ruolo Administrators. Questa volta verrà visualizzato il messaggio "Non si è membri dei ruoli Supervisori o Amministratori. Pertanto non è possibile modificare o eliminare informazioni utente."

Accedere quindi come utente membro del ruolo Supervisori. Questa volta verrà visualizzato il messaggio specifico del ruolo supervisori (vedere la figura 9). E se si accede come utente nel ruolo Administrators si dovrebbe visualizzare il messaggio specifico del ruolo Administrators (vedere la figura 10).

Bruce è mostrato ai supervisori Role-Specific Messaggio

Figura 9: Bruce viene mostrato il messaggio di supervisori Role-Specific (fare clic per visualizzare l'immagine full-size)

Tito viene visualizzato il messaggio Di Role-Specific amministratori

Figura 10: Tito viene visualizzato il messaggio Administrators Role-Specific (Fare clic per visualizzare l'immagine a dimensioni complete)

Mentre le schermate nelle figure 9 e 10 mostrano, loginView esegue il rendering di un solo modello, anche se si applicano più modelli. Bruce e Tito sono entrambi connessi agli utenti, ma LoginView esegue il rendering solo del RoleGroup corrispondente e non dell'oggetto LoggedInTemplate. Inoltre, Tito appartiene ai ruoli Amministratori e Supervisori, ma il controllo LoginView esegue il rendering del modello specifico del ruolo Administrators anziché quello dei supervisori.

La figura 11 illustra il flusso di lavoro usato dal controllo LoginView per determinare quale modello eseguire il rendering. Si noti che se è specificato più di un RoleGroup, il modello LoginView esegue il rendering del primo RoleGroup corrispondente. In altre parole, se è stato inserito il Supervisors RoleGroup come primo RoleGroup e gli amministratori come secondo, quando Tito ha visitato questa pagina, visualizzerà il messaggio Supervisori.

Flusso di lavoro del controllo LoginView per determinare quale modello eseguire il rendering

Figura 11: Flusso di lavoro del controllo LoginView per determinare quale modello eseguire il rendering (fare clic per visualizzare l'immagine full-size)

Limitazione a livello di codice delle funzionalità

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 Eliminazione per i visitatori anonimi e gli utenti che non sono inclusi nel ruolo Supervisori o Amministratori. È necessario nascondere il pulsante Elimina per tutti gli utenti che non sono amministratori. Per eseguire questa operazione, verrà scritto un bit di codice che fa riferimento a livello di codice alla modifica e all'eliminazione di LinkButton di CommandField e imposta le relative Visible proprietà su false, se necessario.

Il modo più semplice per fare riferimento ai controlli a livello di codice in un CommandField consiste nel convertirlo in un modello. A tale scopo, fare clic sul collegamento "Modifica colonne" dal smart tag di GridView, selezionare Il campo di comando nell'elenco dei campi correnti e fare clic sul collegamento "Converti questo campo in un campo Modello". In questo modo il ComandoField viene trasformato in un oggetto TemplateField con un ItemTemplate oggetto e EditItemTemplate. Contiene ItemTemplate i linkButton di modifica ed eliminazione mentre le EditItemTemplate case aggiornano e annullano linkButton.

Convertire commandField in un modellofield

Figura 12: Convertire commandField in un modellofield (fare clic per visualizzare l'immagine full-size)

Aggiornare rispettivamente le proprietà Edit and Delete LinkButtons in ItemTemplate, impostando le relative ID proprietà su valori di EditButton e , DeleteButtonrispettivamente.

<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 Eliminazione per gli utenti non autorizzati, è necessario creare un gestore eventi per questo evento e fare riferimento a livello di codice alle proprietà Edit and Delete LinkButtons, impostandone Visible di conseguenza le proprietà.

Creare un gestore eventi per l'evento RowCreated e quindi aggiungere il codice seguente:

protected void UserGrid_RowCreated(object sender, GridViewRowEventArgs e)
{
     if (e.Row.RowType == DataControlRowType.DataRow && e.Row.RowIndex != UserGrid.EditIndex)
     {
          // Programmatically reference the Edit and Delete LinkButtons
          LinkButton EditButton = e.Row.FindControl("EditButton") as LinkButton;

          LinkButton DeleteButton = e.Row.FindControl("DeleteButton") as LinkButton;

          EditButton.Visible = (User.IsInRole("Administrators") || User.IsInRole("Supervisors"));
          DeleteButton.Visible = User.IsInRole("Administrators");
     }
}

Tenere presente che l'evento RowCreated viene attivato per tutte le righe GridView, tra cui l'intestazione, il piè di pagina, l'interfaccia del pager e così via. Si vuole solo fare riferimento a livello di codice ai pulsanti Modifica ed Eliminazione di link 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 si tratta di una riga di dati che non è in modalità di modifica, i linkButton edit and Delete vengono a cui si fa riferimento e le relative Visible proprietà vengono impostate in base ai valori booleani restituiti dal User metodo dell'oggetto IsInRole(roleName) . L'oggetto User fa riferimento all'entità creata da RoleManagerModule. Di conseguenza, il IsInRole(roleName) metodo usa l'API Ruoli per determinare se il visitatore corrente appartiene a roleName.

Nota

È possibile usare direttamente la classe Roles, sostituendo la chiamata a User.IsInRole(roleName) con una chiamata al Roles.IsUserInRole(roleName) metodo . Si è deciso di usare il metodo dell'oggetto principale in questo esempio perché è più efficiente rispetto all'uso diretto dell'API IsInRole(roleName) Ruoli. 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 usati solo quando viene chiamato il metodo dell'entità IsInRole(roleName) ; le chiamate dirette all'API Ruoli comportano sempre un viaggio nell'archivio ruoli. Anche se i ruoli non vengono memorizzati nella cache in un cookie, chiamare il 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, invece, non esegue alcuna memorizzazione nella cache. Poiché l'evento RowCreated viene attivato una sola volta per ogni riga in GridView, l'uso User.IsInRole(roleName) prevede un solo viaggio nell'archivio ruoli, mentre Roles.IsUserInRole(roleName)richiede n viaggi, 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 è nel ruolo Amministratori o Supervisori; in caso contrario, è impostato su false. La proprietà del Visible pulsante Delete è 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 è un supervisore né un amministratore, il CommandField è vuoto; esiste ancora, ma come sottile sliver senza i pulsanti Modifica o Elimina.

Nota

È possibile nascondere completamente commandField quando un non supervisore e non amministratore sta visitando la pagina. Lascio questo come esercizio per il lettore.

I pulsanti Modifica ed eliminazione sono nascosti per non supervisori e non amministratori

Figura 13: i pulsanti Modifica ed eliminazione sono nascosti per non supervisori e non amministratori (fare clic per visualizzare l'immagine full-size)

Se un utente che appartiene al ruolo Supervisori (ma non al ruolo Amministratori), visualizza solo il pulsante Modifica.

Mentre il pulsante Modifica è disponibile per i supervisori, il pulsante Elimina è nascosto

Figura 14: mentre il pulsante Modifica è disponibile per i supervisori, il pulsante Elimina è nascosto (fare clic per visualizzare l'immagine a dimensioni complete)

E se un amministratore visita, ha accesso sia ai pulsanti Modifica che Elimina.

I pulsanti Modifica ed eliminazione sono disponibili solo per gli amministratori

Figura 15: i pulsanti modifica ed eliminazione sono disponibili solo per gli amministratori (fare clic per visualizzare l'immagine full-size)

Passaggio 3: Applicazione di regole di autorizzazione Role-Based 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à agli amministratori. Questa operazione è stata eseguita nascondendo gli elementi dell'interfaccia utente associati per gli utenti non autorizzati tramite tecniche di programmazione. 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 nascondere per gli utenti non autorizzati. In alternativa, un hacker potrebbe individuare 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 attraverso il quale è possibile definire queste regole.

È stato esaminato l'uso dell'attributo nell'esercitazione Sull'autorizzazione basata sull'utentePrincipalPermission. In particolare, abbiamo visto come decorare rispettivamente il gestore eventi e il gestore eventi SelectedIndexChanged di GridView in modo che possano essere eseguiti solo dagli utenti autenticati e RowDeleting Tito. L'attributo PrincipalPermission funziona anche con i ruoli.

Viene illustrato l'uso dell'attributo PrincipalPermission nei gestori eventi e RowDeleting di RowUpdating GridView per impedire l'esecuzione per gli utenti non autorizzati. Tutto ciò che dobbiamo fare è aggiungere l'attributo appropriato a ogni definizione di funzione:

[PrincipalPermission(SecurityAction.Demand, Role = "Administrators")]
[PrincipalPermission(SecurityAction.Demand, Role = "Supervisors")]
protected void UserGrid_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
     ...
}

[PrincipalPermission(SecurityAction.Demand, Role = "Administrators")]
protected void UserGrid_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
     ...
}

L'attributo per il RowUpdating gestore eventi determina che solo gli utenti nei ruoli Amministratori o Supervisori possono eseguire il gestore eventi, dove come attributo RowDeleting nel gestore eventi limita l'esecuzione agli utenti nel ruolo Administrators.

Nota

L'attributo PrincipalPermission viene rappresentato come classe nello System.Security.Permissions spazio dei nomi. Assicurarsi di aggiungere un'istruzione using System.Security.Permissions nella parte superiore del file di classe code-behind per importare questo spazio dei nomi.

Se, in qualche modo, un non amministratore tenta di eseguire il RowDeleting gestore eventi o se un gestore eventi non supervisore o non amministratore tenta di eseguire il RowUpdating gestore eventi, il runtime .NET genererà un SecurityExceptionoggetto .

Se il contesto di sicurezza non è autorizzato a eseguire il metodo, viene generata un'eccezione SecurityException

Figura 16: se il contesto di sicurezza non è autorizzato a eseguire il metodo, viene generato un SecurityException oggetto (fare clic per visualizzare l'immagine a dimensioni complete)

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 PrincipalPermission è utile anche per applicare le regole di autorizzazione a questi livelli.

Per altre informazioni sull'uso dell'attributo PrincipalPermission per definire le regole di autorizzazione sulle classi e sui metodi, vedere la voce di blog di Scott GuthrieAggiunta di regole di autorizzazione ai livelli di business e dati usando PrincipalPermissionAttributes.

Riepilogo

In questa esercitazione è stato illustrato come specificare regole di autorizzazione di granularità grossolane e fine in base ai ruoli dell'utente. ASP. La funzionalità di autorizzazione URL di NET consente a uno sviluppatore di pagine di specificare quali identità sono consentite o negate l'accesso alle pagine. Come illustrato di nuovo nell'esercitazione Sull'autorizzazione basata sull'utente, è possibile applicare le regole di autorizzazione URL in base all'utente. Possono essere applicati anche in base al ruolo, come illustrato nel passaggio 1 di questa esercitazione.

Le regole di autorizzazione di granularità fine possono essere applicate in modo dichiarativo o a livello di codice. Nel passaggio 2 è stata esaminata l'uso della funzionalità RoleGroups del controllo LoginView per eseguire il rendering di output diverso 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.

Programmazione felice!

Altre informazioni

Per altre informazioni sugli argomenti illustrati in questa esercitazione, vedere le risorse seguenti:

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, allenatore e scrittore. Il suo ultimo libro è Sams Teach Yourself ASP.NET 2,0 in 24 Ore. Scott può essere raggiunto all'indirizzo 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 utili. I revisori principali per questa esercitazione includono Suchi Banerjee e Teresa Murphy. Interessati a esaminare i prossimi articoli MSDN? In tal caso, lasciami una riga in mitchell@4GuysFromRolla.com