Autorizzazione basata sui ruoli (VB)

di Scott Mitchell

Nota

Poiché questo articolo è stato scritto, i provider di appartenenze ASP.NET sono stati sostituiti da ASP.NET Identity. È consigliabile aggiornare le app per usare ASP.NET Identity Platform anziché i provider di appartenenze in primo piano al momento della scrittura di questo articolo. ASP.NET Identity presenta diversi 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
  • Migliore interoperabilità con ASP.Net Core

Scaricare il codice o scaricare il 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 di 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 di consentire solo agli utenti autenticati di visitare una pagina. In alternativa, è possibile determinare che solo gli utenti Tito e Bob sono stati consentiti o indicano che tutti gli utenti autenticati ad eccezione di Sam sono stati 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 di regole di autorizzazione su base utente può diventare 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 di ASP.NET. È possibile iniziare subito.

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 Panoramica dell'autenticazione basata su form, è FormsAuthenticationModule responsabile della determinazione dell'identità del richiedente, eseguita durante l'eventoAuthenticateRequest.

Se viene trovato un ticket di autenticazione non scaduto valido, 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'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 principal hanno una Identity proprietà e un IsInRole(roleName) metodo. L'oggetto FormsAuthenticationModule, tuttavia, non è interessato alla registrazione delle informazioni sui ruoli e l'oggetto GenericPrincipal creato non specifica alcun ruolo.

Se il framework dei ruoli è abilitato, il RoleManagerModule modulo HTTP viene eseguito dopo FormsAuthenticationModule e identifica i ruoli dell'utente autenticato durante l'eventoPostAuthenticateRequest, che viene generato dopo l'eventoAuthenticateRequest. Se la richiesta proviene da un utente autenticato, l'oggetto RoleManagerModuleGenericPrincipal viene sovrascritto da FormsAuthenticationModule e lo sostituisce con un RolePrincipal oggetto . La RolePrincipal classe usa l'API Roles per determinare a quali ruoli 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. Viene FormsAuthenticationModule eseguito per primo, identifica l'utente tramite il ticket di autenticazione e crea un nuovo GenericPrincipal oggetto. Successivamente, i RoleManagerModule passaggi in e sovrascrive l'oggetto GenericPrincipal con un RolePrincipal oggetto .

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

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

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)

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 ruoli. Quando si usano regole di autorizzazione URL basate su ruoli, il RolePrincipalmetodo del IsInRole metodo verrà chiamato in ogni richiesta a una pagina protetta dalle regole di autorizzazione degli URL basate su ruoli. Invece di 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 roles è configurato per memorizzare nella cache i ruoli dell'utente in un cookie, il RoleManagerModule crea il cookie durante l'evento della pipeline di EndRequestASP.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ì da RolePrincipal dover effettuare una chiamata alla Roles classe per determinare i 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 a dimensione intera)

Per impostazione predefinita, il meccanismo del cookie della cache dei ruoli è disabilitato. Può essere abilitato tramite il markup di <roleManager>configurazione in Web.config. È stato illustrato come usare l'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 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 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.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 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 theattribute, 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 smallermaxCachedResults' value; contrariamente, se si dispone di 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 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>

L'elemento <roleManager>è stato aggiornato aggiungendo tre attributi: cacheRolesInCookie, createPersistentCookiee cookieProtection. Impostando cacheRolesInCookie su true, l'oggetto RoleManagerModule memorizza automaticamente nella cache i ruoli dell'utente in un cookie invece di dover cercare le informazioni sul ruolo dell'utente in ogni richiesta. Gli attributi e vengono cookieProtection impostati createPersistentCookie in modo esplicito rispettivamente su false e All. Tecnicamente, non ho bisogno di specificare i valori per questi attributi perché li ho appena assegnati ai valori predefiniti, ma li ho inseriti qui per chiarire esplicitamente che non uso cookie persistenti e che il cookie è sia crittografato che convalidato.

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

Nota

Il gruppo Criteri di Microsoft & Practices sconsiglia l'uso dei cookie della 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 che 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 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 <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 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 si scriverà codice che chiama .MembershipGetAllUsers metodo e associa l'oggetto risultante MembershipUserCollection a GridView. Contiene un MembershipUser oggetto per ogni account utente nel sistema. MembershipUser Gli MembershipUserCollection oggetti hanno proprietà come UserName,EmailLastLoginDatee 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 ognuna delle ItemTemplates proprietà e associarne Text le 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 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, è 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. Il Membership.FindUsersByName metodo è 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. GridView UserGrid , 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 , RowCancelingEdit, RowUpdatinge RowDeleting di RowEditingGridView, che vengono attivati quando un visitatore fa clic sui pulsanti Edit, Cancel, Update o Delete di GridView.

Per iniziare, creare i gestori eventi per gli eventi , RowCancelingEdite RowUpdating di RowEditingGridView 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 RowEditing gestori eventi e RowCancelingEdit impostano semplicemente la proprietà di EditIndex GridView e quindi ribindevano l'elenco di account utente sulla griglia. Le cose interessanti avvengono nel RowUpdating gestore eventi. Questo gestore eventi inizia assicurandosi che i dati siano validi e quindi recupera il UserName valore dell'account utente modificato dalla DataKeys raccolta. Le Email caselle di testo e Comment nei due campi template 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 viene eseguita tramite una chiamata a Membership.GetUser(userName). Le proprietà e Comment dell'oggetto Email restituito 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 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 afferrando il UserName valore dalla raccolta di DataKeys GridView. Questo UserName valore viene quindi passato al metodo della DeleteUserclasse 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 EditIndex , la griglia è 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 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 altre 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. È possibile 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 le istruzioni specifiche del ruolo dell'utente. Se una persona nel ruolo Amministratori visita questa pagina, verranno visualizzate 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 è possibile modificare o eliminare le informazioni sull'account utente. Nella sezione "Limitazione delle 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, aggiungere un controllo 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 può modificare o eliminare informazioni sull'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à, 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 gruppi di ruoli, fare clic sul collegamento "Modifica gruppi di ruoli" dallo Smart Tag del controllo per visualizzare l'Editor raccolta RoleGroup. Aggiungere due nuovi RoleGroup. Impostare la proprietà del Roles primo RoleGroup su "Administrators" e la seconda su "Supervisori".

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

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

Fare clic su OK per chiudere l'Editor raccolta RoleGroup; in questo modo viene aggiornato il markup dichiarativo di LoginView per includere una <RoleGroups> sezione con un <asp:RoleGroup> elemento figlio per ogni RoleGroup definito nell'Editor raccolta RoleGroup. Inoltre, l'elenco a discesa "Visualizzazioni" nello smart tag di LoginView, inizialmente elencato solo AnonymousTemplate da e LoggedInTemplate , ora include anche i RoleGroup aggiunti.

Modificare i Gruppi di ruoli 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 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 sull'utente." Accedere quindi come utente autenticato, ma uno che non è né nel ruolo Supervisori né Amministratori. Questa volta verrà visualizzato il messaggio "You are not a member of the Supervisors or Administrators roles. Pertanto, non è possibile modificare o eliminare informazioni sull'utente."

Accedere quindi come utente membro del ruolo Supervisors. Questa volta dovrebbe essere visualizzato il messaggio specifico del ruolo supervisori (vedere la figura 9). Se si accede come utente nel ruolo Amministratori, verrà visualizzato il messaggio Specifico del ruolo Amministratori (vedere la figura 10).

Bruce è mostrato i supervisori Role-Specific Messaggio

Figura 9: Bruce mostra i supervisori Role-Specific messaggio (fare clic per visualizzare l'immagine a dimensione intera)

Tito viene visualizzato il messaggio Administrators Role-Specific

Figura 10: Viene visualizzato il messaggio Administrators Role-Specific (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.

La figura 11 illustra il flusso di lavoro usato dal controllo LoginView per determinare il modello di cui 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 avessimo inserito il Supervisors RoleGroup come primo RoleGroup e gli Amministratori come secondo, quando Tito visitò questa pagina visualizzò 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 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é nei ruoli Supervisori né Amministratori. È necessario nascondere il pulsante Elimina per tutti gli utenti che non sono amministratori. Per eseguire questa operazione, si scriverà un po' di codice che fa riferimento a livello di codice ai pulsanti Edit e Delete LinkButton di CommandField e ne imposta le Visible proprietà su False, se necessario.

Il modo più semplice per fare riferimento ai controlli a livello di codice in un campo CommandField consiste innanzitutto nel convertirlo in un modello. A tale scopo, fare clic sul collegamento "Modifica colonne" dallo 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 campo CommandField viene trasformato in un oggetto TemplateField con un ItemTemplate oggetto e EditItemTemplate. ItemTemplate Contiene i pulsanti Modifica ed Elimina linkbutton mentre ospita EditItemTemplate i pulsanti Update e Cancel LinkButton.

Convertire il campo CommandField in un campo modello

Figura 12: Convertire il campo di comando in un campo modello (fare clic per visualizzare l'immagine a dimensione intera)

Aggiornare i pulsanti Modifica ed Elimina link in ItemTemplate, impostandone ID le proprietà rispettivamente sui 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 LinkButton, 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 cercapersone 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 include 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, viene fatto riferimento ai pulsanti di modifica ed eliminazione 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 Roles 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 . In questo esempio ho deciso di usare il metodo dell'oggetto IsInRole(roleName) principal perché è più efficiente rispetto all'uso 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 all'API Ruoli comportano sempre un viaggio nell'archivio ruoli. Anche se i ruoli non vengono memorizzati nella cache in un cookie, la chiamata al metodo dell'oggetto IsInRole(roleName) principal è in genere più efficiente perché quando viene chiamata 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 un solo 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 sottile scivolare senza i pulsanti Modifica o Elimina.

Nota

È 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.

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 a dimensione intera)

Se un utente appartenente al ruolo Supervisori (ma non al ruolo Amministratori) visita, 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 dimensione intera)

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

I pulsanti Modifica ed Elimina sono disponibili solo per gli amministratori

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 Role-Based a classi e metodi

Nel passaggio 2 sono state limitate le funzionalità di modifica per gli utenti nei ruoli Supervisori e Amministratori ed eliminare solo le funzionalità per gli amministratori. Questa operazione è stata eseguita nascondendo gli elementi dell'interfaccia utente associati per gli 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 che vengono aggiunti in un secondo momento o che si è dimenticato di nascondere 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 un particolare elemento di funzionalità non possa essere accessibile da 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 delle autorizzazioni. L'attributo PrincipalPermission fornisce un meccanismo tramite il quale è possibile definire queste regole.

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

Di seguito viene illustrato come usare l'attributo PrincipalPermission nei gestori eventi e RowDeleting di RowUpdating GridView per impedire l'esecuzione per 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.

Nota

L'attributo PrincipalPermission è rappresentato come classe nello spazio dei System.Security.Permissions nomi . Assicurarsi di aggiungere un'istruzione Imports System.Security.Permissions all'inizio 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 non supervisore o non amministratore tenta di eseguire il RowUpdating gestore eventi, il runtime .NET genererà un oggetto SecurityException.

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 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 eseguire la logica di business e le funzionalità correlate ai dati. L'attributo PrincipalPermission è utile anche per l'applicazione di regole di autorizzazione a questi livelli.

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

Riepilogo

In questa esercitazione è stato illustrato come specificare regole di autorizzazione grossolane e granulari 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 degli URL in base all'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 diverso in base ai ruoli dell'utente in visita. Sono stati anche 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 descritti in questa esercitazione, vedere le risorse seguenti:

Informazioni sull'autore

Scott Mitchell, autore di più libri ASP/ASP.NET e fondatore di 4GuysFromRolla.com, lavora 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 all'indirizzo mitchell@4guysfromrolla.com o tramite il suo blog all'indirizzo http://ScottOnWriting.NET.

Grazie speciale...

Questa serie di esercitazioni è stata esaminata da molti revisori utili. I revisori principali di questa esercitazione includono Suchi Banerjee e Teresa Murphy. Si è interessati a esaminare i prossimi articoli MSDN? In tal caso, lasciami una riga in mitchell@4GuysFromRolla.com