venerdì 2 dicembre 2011

Impedire l'esecuzione del programma .NET ad un utente che non sia amministratore

Un esigenza molto comune per esempio, se si vuole fare una console di amministazione di un servizio è quella che un applicazione o un metodo siano eseguiti solo se l'utente appartiene ad un determinato gruppo che ha i permessi necessari, per esempio ad accedere ad una determinata risorsa. Nel seguente esempio scritto in C# se l'utente che esegue il thread non è un amministratore allora il metodo genera un eccezione e si può chiudere l'applicazione.

Come prima cosa bisogna applicare i criteri principali del dominio applicazione corrente a WindowsPrincipal, altrimenti una richiesta di autorizzazione principale avrà esito negativo.
AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
Ora abbiamo bisogno di sapere quale è l'utente che sta eseguendo il thread corrente.
//Estrae l'identità dell'utente del thread corrente
WindowsIdentity wi = (WindowsIdentity)System.Threading.Thread.CurrentPrincipal.Identity;
                
//Estrae il nome utente da suo sid
IdentityReference mYaccount = wi.User.Translate(typeof(NTAccount));
//Visualizza il nome utente estratto da suo sid
MessageBox.Show("Utente:" + mYaccount.Value);
Adesso dobbiamo ricavare il gruppo administrator da assegnare alla funzione di controllo. Per aiutarvi potete visualizzare i nomi dei gruppi a cui l'utente del thread appartiene così:
StringBuilder sbMsg = new StringBuilder();
foreach (IdentityReference sidRef in wi.Groups)
{
    IdentityReference account = sidRef.Translate(typeof(NTAccount));
    sbMsg.AppendLine(account.Value);
}
MessageBox.Show(sbMsg.ToString());
Ora per impedire all'applicazione di partire se non siamo amministratori, usiamo le seguenti istruzioni:
try
{
    PrincipalPermission permessi = 
        new PrincipalPermission(mYaccount.Value, "BUILTIN\\Administrators");
                
    permessi.Demand();
}
catch (SecurityException ex)
{
   MessageBox.Show(ex);
   //Esci dall'applicazione
}