Sicurezza e autenticazione in Asp.Net

Asp.Net mette a disposizione una serie di controlli per la gestione degli utenti, includendo sia la parte di front end come i form di registrazione, login, ecc sia le tabelle di database. Questo per evitare di scrivere codice che può risultare lungo e ripetitivo, ed essere subito operativi.

Tenere ben presente che le impostazioni e le configurazioni relative alla Sicurezza vengono memorizzate in parte nei file di configurazione machine/web.config e in parte in un database dedicato. Questo database si chiama aspnetdb.mdf (LocalSqlServer per la Connection String) e viene creato automaticamente da Asp.Net nella cartella speciale App_Data nel momento in cui si utilizza un controllo Login.

Impostare il database

E' anche possibile usare un database diverso rispetto a quello predefinito, ad esempio il db principale del sito in modo da usarne uno solo. Per fare questo bisogna prima abilitarlo alle Application Services: in pratica si tratta di lanciare un eseguibile che crea nel db le tabelle necessarie per la gestione della sicurezza.

Lanciare aspnet_regsql e dargli in pasto il database da abilitare.

C:\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet_regsql.exe

Vengono create le seguenti tabelle, facilmente distinguibili da quelle già presenti grazie al prefisso.

Vengono create anche viste e stored procedures.

Occorre poi sovrascrivere la stringa di connessione di Default con una personale, che va aggiunta a quella già presente per il proprio data base.
Nota: LocalSqlServer è un nome non modificabile.

<connectionStrings>
	<clear />
	...
	<add name="LocalSqlServer" providerName="System.Data.SqlClient" 
		connectionString="Server=localhost; User ID=sergio; Password=xxx; Database=Dev-oClock-DB;" />
</connectionStrings>

Controlli Login

In Visual Studio sono presenti 7 controlli relativi alla sicurezza e si trovano nella sezione Login.

  • Login: form di login; visibile anche per gli utenti autenticati
  • LoginStatus: link di login/logout
  • LoginName: nome dell'utente loggato; si può usare ad esempio per un messaggio di benvenuto
  • ChangePassword: permette agli utenti autenticati di modificare la propria password
  • CreateUserWizard: modulo per la creazione utente
  • PasswordRecovery: permette agli utenti autenticati di recuperare o resettare la propria password
  • LoginView: permette di mostrare contenuto specifico per determinati utenti o gruppi di utenti

Per ulteriori informazioni consultare le guide su msdn.

Configurare i controlli Login

Il comportamento dei controlli Login può essere in parte modificato semplicemente impostandone le proprietà.
Altre impostazioni invece si trovano nel file di configurazione machine.config. E' sconsigliabile modificare questo file visto che influenza tutte le applicazioni .Net della macchina, inoltre a volte non è neanche possbile modificarlo (as esempio nei siti hostati da terze parti).

La soluzione quindi è sovrascrivere i parametri nel file web.config del proprio sito.

<membership>
	<providers>
		<clear />
		<add name="AspNetSqlMembershipProvider"
			type="System.Web.Security.SqlMembershipProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
			connectionStringName="LocalSqlServer"
			enablePasswordRetrieval="false"
			enablePasswordReset="true"
			requiresQuestionAndAnswer="false"
			applicationName="/"
			requiresUniqueEmail="false"
			passwordFormat="Hashed"
			maxInvalidPasswordAttempts="5"
			minRequiredPasswordLength="8"
			minRequiredNonalphanumericCharacters="1"
			passwordAttemptWindow="10"
			passwordStrengthRegularExpression=""/>
	</providers>
</membership>

Controllo LoginView

Questo controllo è particolamente interessante perché è quello che effettivamente contiene dei template visibili solo da determinati utenti o gruppi di utenti. Ecco un esempio:

<!-- mostra il nome dell'utente loggato; se non è loggato non mostra nulla -->
<asp:LoginName ID="LoginName1" runat="server"  FormatString="Logged in as {0}" />

<asp:LoginView ID="LoginView1" runat="server">
	<AnonymousTemplate>
		<!-- contenuto visibile solo per gli utenti non loggati:
			 ci metto ad esempio il form di login e il recupera password -->
		
		<!-- Form di Login -->
		<asp:Login ID="Login1" runat="server" CreateUserText="Login"
					CreateUserUrl="Login.aspx">
		</asp:Login>
		<br />
		<!-- Recupero password -->
		<asp:PasswordRecovery runat="server" id="PasswordRecovery1">
			<MailDefinition Subject="Password dimenticata"></MailDefinition>		
		</asp:PasswordRecovery>
	
	</AnonymousTemplate>
	<LoggedInTemplate>
		<!-- contenuto visibile solo dagli utenti loggati -->
		... 
	</LoggedInTemplate>
						
	<RoleGroups>						
		<asp:RoleGroup Roles="Amministratori">
			<ContentTemplate>
				<!-- contenuto visibile solo dagli utenti appartenenti al gruppo Amministratori -->
				<asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl="/BackOffice/Default.aspx">Gestione Sito</asp:HyperLink>
			</ContentTemplate>
		</asp:RoleGroup>
	</RoleGroups>
</asp:LoginView>

Gestire i Ruoli

Per ruolo si intende un gruppo di utenti. Un utente può appartenere a più ruoli.
Tutto questo è gestibile tramite WSAT (Web Site Administration Tool):

Visual Studio >> Website >> ASP.NET Configuration >> Security

Proteggere cartelle e files

E' possibile bloccare l'accesso a determinate cartelle in modo visuale dalla sezione Access Rules di WSAT.
Questo però genera un file web.config in ogni cartella, quindi non si ha una visione globale di tutte le impostazioni.
Risulta più comodo creare le regole manualmente all'interno del file web.config che si trova nella root del sito.

<configuration>
	...
	<!-- Consento l'accesso alla cartella BackOffice solo agli utenti dei gruppi Administrators e Editors -->
	<location path="BackOffice">
		<system.web>
			<authorization>
				<allow roles="Administrators,Editors"/>
				<deny users="*"/>
			</authorization>
		</system.web>
	</location>

	<!-- Blocco l'accesso alla cartella Articoli a tutti gli utenti non autenticati -->
	<location path="Atricoli">
		<system.web>
			<authorization>
				<deny users="?"/>
			</authorization>
		</system.web>
	</location>

</configuration>

Controllare i ruoli via codice

Quando invece è necessario prendere decisioni all'interno del codice si può usare la notazione User.IsInRole per verificare se un utente appartiene a un ruolo.

If User.IsInRole("Editors") Then
	...
End If

In modo analogo è possibile visualizzare e gestire utenti e ruoli programmaticamente, ad esempio per creare una sezione di gestione utenze.

Autore: Sergio Roberto Boarina