A volte può essere utile cambiare l'account con cui si esegue una porzione di codice, p.es. per ottenere dei livelli di trust più elevati. Si possono:
- Utilizzare credenziali di rete differenti;
- Acquisire le credenziali di account differenti.
Il primo caso è più comune in applicazioni che fanno uso di servizi sulla rete (accedono a pagine web o servizi web) ma che eseguono la maggior parte delle operazioni in locale. In tal caso una impersonation completa potrebbe essere inopportuna (l'utente di rete potrebbe non possedere permessi importanti in locale, come p.es. l'accesso al filesystem per salvare dei file). Si instanzia in questo caso la classe NetworkCredentials, che viene utilizzata per la connessione.
Il secondo caso si verifica quando un'applicazione ha necessità di acquisire dei permessi specifici per breve tempo, come p.es. scrivere o leggere su una share di rete da un'applicazione web che giri in un contesto utente non modificabile (p.es. un utenza NetworkService di un'application pool, per ragioni di sicurezza). In tal caso è possibile acquisire per breve tempo un contesto utente differente, eseguire delle operazioni ed infine tornare al contesto di partenza utilizzando le API di sistema.
Prima debbono essere dichiarati i metodi:
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
public static extern int LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, uint dwLogonType, uint dwLogonProvider, ref IntPtr phToken);
[DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
public static extern bool CloseHandle(IntPtr handle);
Che verranno utilizzati per effettuare il logon e l'impersonation:
int hresult = LogonUser(username, domain, password, (uint)LogonSessionType.Interactive, (uint)LogonProvider.LogonDefault, userToken);
WindowsIdentity identity = new WindowsIdentity(userToken); WindowImpersonationContext context = identity.Impersonate;
Che può essere poi rilasciato:
context.Undo();
Luc.
Impersonator.zip (,83 KB)