Step 3: Indicare le pagine da proteggere nel web.config
Ricordate il tag location analizzato nell'articolo ASP.NET Windows Authentication ?
Vediamone un breve tratto.
Le impostazioni sulle autorizzazioni per utenti si effettuano nel file Web.Config dell’applicazione.
I tag per configurare gli accessi all’intera applicazione sono autoesplicativi:
<authorization>
<deny users=“?” />
</authorization>
La sezione <authorization> deve essere inserita nella sottosezione <system.web> della sezione <configuration>.
In questo semplice esempio abbiamo protetto l'intero sito dall'accesso anonimo.
La sezione <authorization> può contentere il tag <deny> per negare l'accesso all'utente oppure il tag <allow> per consentire l'accesso.
I settaggi si applicano secondo la regola “First Match Wins”.
Quindi nell’esempio seguente il secondo tag verrebbe ignorato
<allow users=”RobertoB” />
<deny users=”RobertoB” />
in quanto, a fronte di un accesso di RobertoB, il primo tag ha un match esatto con l’utente (consentendogli l’accesso).
Esistono due caratteri speciali, “*” e “?”, che significano rispettivamente “All users” e “Anonymous User”.
Rimandiamo all'articolo ASP.NET Windows Authentication sia per un approfondimento dei vari tag che per capire le interazioni fra i web.config nella gerarchia applicativa e le relazioni con il file di configurazione della macchina machine.config, che, ricordiamo contiene un <allow users="*" />.
Il tag <location> da inserire nella sezione <configuration>, fuori dalla sezione <system.web> consente di indicare <allow> e <deny> per path specifici (sia directory che singoli file).
Ad esempio:
<location path="Pagina.aspx">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>
consente di autorizzare l'accesso anonimo per la pagina "Pagina.aspx" indipendentemente dalle impostazioni globali della sezione <system.web>, che nel nostro esempio iniziale conteneva un <deny uses="?" />.
N.B. La pagina di login ovviamente deve essere accessibile senza credenziali, altrimenti sarebbe impossibile effuttuare un login.
Il meccanismo di Forms Authentication per default rende accessibile all'utente anonimo la pagina di login indicata nello Step 2: non è necessario quindi inserire il tag <location path="Login.aspx"> per consentire all'utente anonimo l'accesso alla pagina Login.aspx.
Step 4: Configurare utenti e relative password nel file web.config
Nella sezione <forms> precedentemente inserita occorre indicare le credenziali degli utenti che verranno verificate ad ogni request dal meccanismo di autenticazione.
Questo un esempio:
<credentials passwordFormat = "Clear">
<user name="RobertoB" password="Pippo"/>
<user name="LucaR" password="Pippo"/>
</credentials>
Il tag <credential>, indica che il cookie conterrà l'indicazione dell'account utente in chiaro.
Vedremo più avanti come utilizzare algoritmi di cripting per "proteggere" il contenuto del cookie di autenticazione.
Seguono i due account utilizzati nell'esempio i cui tag sono autoesplicativi.
N.B. Secondo la tradizione Windows, la password è case sensitive, mentre l'account non lo è: questo significa che la coppia "robertob/Pippo" è valida, ma "RobertoB/pippo" non lo è.
Step 5: Costruire la pagina di login utilizzando le classi fornite per validare l'autenticazione
Di seguito la pagina Login.aspx utilizzata nell'esempio e scaricabile dal sito (Clicca quì).
Per installare l'esempio è sufficiente scompattare lo zip in una virual directory in IIS
Questa il codice della pagina Login.aspx:
<%@Page<%@ Import Namespace="System.Security.Principal" %>
<html>
<head>
<title>Login per Custom Roles</title>
<LINK rel="stylesheet" type="text/css" href="Style.css">
</head>
<body>
<form runat="server">
<p>
<asp:Label ForeColor="Red" ID="lblErrore" runat="server" />
</p>
Username
<asp:TextBox ID="txtUserName" runat="server" />
<br>
Password
<asp:TextBox ID="txtPassword" runat="server" />
<br>
<asp:Button ID="cmdValida" Text="Login" Runat="server" OnClick="cmdValida_Click" />
</form>
</body>
</html>
La parte di interfaccia utente contiene due campi (txtUserName e txtPassword) di input e il pulsante (cmdValida) che scatena l'evento onClick.
Il codice seguente consente di intercettare l'evento onclick e eseguire l'autenticazione dell'utente.
<script language="C#" runat="server">
protected void cmdValida_Click(Object Sender, EventArgs E)
{
if(FormsAuthentication.Authenticate(txtUserName.Text, txtPassword.Text))
FormsAuthentication.RedirectFromLoginPage(txtUserName.Text, false);
else
lblErrore.Text = "Login Invalido !";
}
</script>
Come si vede il metodo Authenticate consente di verificare username e password inseriti dall'utente nel form di login.
Il metodo restituisce true se username e password sono presenti nel file web.config (come abbiamo visto nello step 4).
A fronte di un utente invalido viene riempita la label (lblErrore) con l'indicazione dell'errore.
Il metodo RedirectFromLoginPage invece redirige l'utente verso la pagina richiesta inizialmente (prima della redirezione atuomatica verso la pagina di login).
Questo metodo accetta due parametri:
Il primo indica il valore da inserire nel cookie di autenticazione: questo valore viene controllato rispetto all'elenco degli utenti presente nel file web.config.
Il secondo (true/false) indica la persistenza del cookie sul client.
False significa inviare al client un cookie temporaneo (di sessione se volete) che viene distrutto dal client con la chiusura del browser stesso.
Questo significa che alla riapertura del browser l'utente sarà costretto ad effettuare nuovamente il login.
True significa inviare un cookie persistente che il browser appoggerà su disco.
Questo significa che alla riapertura del browser, quest'ultimo recupererà dal disco del client il cookie e lo invierà al sito web in questione, non rendendo così necessario il passaggio dalla pagina di login.
In ogni caso il valore del cookie contiene solo lo username e non verrà controllato rispetto all'elenco degli utenti presente nel file web.config (configurato nello Step 4) ad ogni richiesta del client.
Il codice necessario per eseguire test sugli utenti dalle pagine ASPX è semplice e soprattutto identico a quanto visto nell'articolo ASP.NET Windows Authentication:
If User.Identity.Name = "RobertoB" Then
End If
Sicuramente non è particolarmente indicato eseguire controlli da codice sui singoli utenti.
Per questo, in un altro articolo vedremo come costruire ruoli custom per la gestione delle autorizzazioni sulle risorse e il codice per eseguire test su utenti e ruoli. L'articolo sarà ASP.NET Forms Authentication Custom Roles
Abbiamo visto tutti gli step per configurare la Forms Authentication nella sua veste più semplice.
Ovviamente è possibile scrivere una pagina di login che controlli utenti e password (oppure email o qualunque altro valore di login) in un database: questo argomento sarà presentato in un articolo separato il cui titolo sarà ASP.NET Custom Forms Authentication.
Ricordiamo comunque che gli account utilizzati dalla Forms Authentication sono account .NET e non Security Principal Windows.
Di conseguenza non possiamo proteggere le nostre risorse dal file system di Windows.
Un processo Windows (con codice .NET o meno) deve comunque utilizzare un Security Principal Windows per poter girare e interagire con il sistema operativo.
Questo significa che il processo ASP.NET (ASPNET_WP) dovrà girare con un account Windows...sempre che il sistema operativo “sotto” sia Windows...(a buon intenditore...poche parole)
Tale account, nella versione definitiva di .NET, è ASPNET. L'account viene creato dall'installazione di ASP.NET.
Per modificare tale account occorre modificare l'attributo userName nel file machine.config (nella directory X:\WINNT\Microsoft.NET\Framework\versione\CONFIG).
Oltre a modificare l'attributo occorre indicare la password dell'utente windows da utilizzare.
Un'impostazione comune è
userName="SYSTEM"
password="AutoGenerate"
per far girare il processo ASP.NET con l'account SYSTEM nativo su Windows NT4, Windows 2000, Windows XP.
password="Autogenerate" consente di non dover specificare la password per l'account di sistema.
N.B dopo la modifica delle credenziali del processo è necessario stoppare ASPNET_WP. Ricordiamo che il processo riparte a fronte della prima richiesta di una pagina ASPX sulla macchina.
Un ultima cosa prima di lasciarci:
E' possibile applicare un algoritmo di hashing per "proteggere" le password nel file web.config.
<forms loginUrl=“Login.aspx”>
<credentials passwordFormat=“SHA1”>
<user name="RobertoB" password=“932734577543AAB67B67FFB5”/>
<user name="LucaR" password=“932734577543AAB67B67FFB5”/>
</credentials>
</forms>
Il calcolo dell’hash durante l'autenticazione è automatico rispetto a quanto indicato dall'utente nel campo password della pagina di login.
Infatti il metodo Authenticate(user, password) esegue il calcolo dell'hash in automatico a seconda dell'impostazione passwordFormat del tag <credential>
Gli algoritmi utilizzabili sono: SHA1, come nell'esempio precedente o il più "sicuro", ma più lento, MD5.
Per ottenere i valori da inserire nel web.config la classe FormsAuthentication mette a disposizione il seguente metodo (il più lungo direi in .NET):
HashPasswordForStoringInConfigFile(“Pippo”,”sha1”)
I parametri sono rispettivamente: la stringa originale e l'algoritmo da utilizzare su tale stringa.
Le password di RobertoB e LucaR indicate precedentemente (932734577543AAB67B67FFB5) sono il risultato che ho ottenuto dell'algoritmo SHA1 su "Pippo".
