Nei post [MCAD.31] e [MCAD.33] abbiamo visto come
lavorare con
.NET avendo a che fare con la CAS (Code Access Security ),
ovvero come assegnare o revocare
dei permessi in base all'origine e all' "affidabilità" del codice che sta per
essere eseguito. In base all'URL di provenienza, a seconda che l'assembly
venga eseguito dalle directory locali del proprio PC oppure dalla Intranet, il
runtime .NET assegna un permission sets piuttosto che un altro. Abbiamo visto
come usare caspol.exe
oppure
il tool analogo (Microsoft .NET Framework 1.1 Configuration) per amministrare i permessi
in modo congruo con quello che ci interessa fare.
Esiste anche una seconda possibilità, identica a quella che veniva usata
nell'era pre .NET. Ovvero, assegnare dei permessi in base all'utente attualmente
loggato sul PC, oppure al suo gruppo di appartenenza. Questa logica viene
implementata attraverso le classi WindowsIdentity e
WindowsPrincipal: vediamo come usarle correttamente.
Come rilevare l'utente
corrente ed il suo gruppo di appartenenza
Innanzitutto occorre
dichiarare l'uso del namespace System.Security.Principal. Fatto
questo, possiamo utilizzare le classi WindowsIdentity e
WindowsPrincipal. La prima classe fa riferimento ad un
Identity, ovvero ad uno user di Windows, mentre la seconda classe è utile perchè
espone un metodo IsInRole che ci permette di capire se un certo
utente appartiene ad un gruppo specifico passato come parametro.
Vediamo
qualche riga di codice veloce veloce:
WindowsIdentity io = WindowsIdentity.GetCurrent();
StringBuilder testo = new StringBuilder(string.Empty);
testo.AppendFormat("Tipo di autenticazione : {0}; ", io.AuthenticationType);
testo.AppendFormat("Username : {0}; ", io.Name);
testo.AppendFormat("E' anonimo? : {0}; ", io.IsAnonymous);
testo.AppendFormat("E' autenticato? : {0}", io.IsAuthenticated);
Il metodo statico GetCurrent() ritorna un'istanza relativa
all'utente correntemente loggato nel dominio. Mi sono divertito ad usare la
classe StringBuilder per costruirmi una stringa da
mostrare in una bella TextBox sul mio
WF di prova. La property Name ritorna una stringa
formattata come: DOMAIN\Username. Nel mio caso, sul mio PC di casa, mi ha
ritornato "TERRA\Igor". Le altre property IsAnonymous e
IsAuthenticated ritornano rispettivamente valori booleani che
indicano se l'utente è anonimo (nel mio caso, false), e
se l'utente è stato autenticato (per me true).
Già con queste property possiamo divertirci e adattare l'esecuzione del
codice in modo opportuno. Per esempio, abilitare un MenuItem
solo se lo username è "Admin". Tramite la classe
WindowsPrincipal possiamo invece risalire al gruppo di
appartenenza dell'utente stesso.
WindowsPrincipal prin = new WindowsPrincipal(io);
if (prin.IsInRole(WindowsBuiltInRole.Administrator))
testo.Append("; Fai parte degli Administrators!");
Il metodo IsInRole possiede 3 overload diversi: posso usare
l'enum WindowsBuiltInRole (come nell'esempio qui sopra), posso
usare un valore int (???)
oppure, infine, posso usare una string
. La chiamata al metodo IsInRole
ritorna un valore boolean che ci dice se l'utente passato nel costruttore di
WindowsPrincipal appartiene o meno al gruppo passato
come parametro.
Il codice qui sopra mi dice se appartengo al gruppo degli Administrators: nel mio caso, sì.
Purtroppo, non sono riuscito ad ottenere lo stesso risultato usando come
parametro una string: ho provato
"DOMINIO\Administrators", "DOMINIO\Administrator" e tutte le possibili varianti
(usare il nome del PC al posto del dominio, per esempio), ma in tutti i casi mi
ha sempre ritornato false.
Con l'enum WindowsBuiltInRole nessun problema:
continuerò, se mi servirà, ad usare questo.
Sicuramente c'è ancora molto da dire, ma...
Quando si ha
a che fare con la sicurezza delle applicazioni, c'è sempre molto da dire e molto
da imparare. Se siccome il giorno dell'esame si avvicina, chiudo qua il
discorso.
I prossimi post saranno più che altro mirati a parlare degli
argomenti "minori" che ho tralasciato, come i files *.config (che odio, non
sopporto e, ne sono certo, all'esame mi fregheranno) ed alcuni tools della
command-line come tlbimp.exe ed affini. Qualsiasi suggerimento
è, come al solito, ben accetto!
Alla prossima...