.NET dispose d'une fonctionnalité qui permet d'exécuter du code sous un autre nom d'utilisateur que celui qui a lancé le programme à l'origine (une sorte de RUNAS). C'est un peu compliqué à utiliser car il faut notamment P/Invoker des fonctions de l'API Windows.
Voici un portage du code C# originellement publié par Michiel van Otegem en VB.NET. Cette classe permet de simplifier le basculement de contexte.
Imports System Imports System.Runtime.InteropServices Imports System.Security.Principal Imports System.Security.Permissions Imports Microsoft.VisualBasic Imports System.ComponentModel Imports System.Diagnostics ' Classe qui permet d'exécuter du code sous un autre nom d'utilisateur Public Class WrapperImpersonationContext Private Declare Auto Function LogonUser Lib "advapi32.dll" ( _ ByVal lpszUsername As [String], _ ByVal lpszDomain As [String], ByVal lpszPassword As [String], _ ByVal dwLogonType As Integer, ByVal dwLogonProvider As Integer, _ ByRef phToken As IntPtr) As Boolean Public Declare Auto Function CloseHandle Lib "kernel32.dll" ( _ ByVal handle As IntPtr) As Boolean Private Const LOGON32_PROVIDER_DEFAULT As Integer = 0 Private Const LOGON32_LOGON_INTERACTIVE As Integer = 2 Private _domain As String Private _username As String Private _password As String Private _token As IntPtr Private _context As WindowsImpersonationContext Protected ReadOnly Property InContext() As Boolean Get Return Not _context Is Nothing End Get End Property ' Constructeur ' Le nom de domaine peut être laissé vide et on peut passer ' le nom d'utilisateur sous la forme utilisateur@domain Public Sub New(ByVal domain As String, ByVal username As String, _ ByVal password As String) Dim pos As Integer = username.IndexOf("@") If pos <> -1 Then _username = username.Substring(0, pos) _domain = username.Substring(pos + 1) Else _domain = domain _username = username End If _password = password End Sub <PermissionSetAttribute(SecurityAction.Demand, Name:="FullTrust")> _ Public Sub Enter() If Me.InContext Then Return _token = IntPtr.Zero Try Dim logonSuccessFull As Boolean = LogonUser(_username, _domain, _ _password, LOGON32_LOGON_INTERACTIVE, LOGON32_LOGON_INTERACTIVE, _ _token) If Not logonSuccessFull Then Dim err As Integer = Marshal.GetLastWin32Error() Throw New Win32Exception(err) End If Dim identity As WindowsIdentity = New WindowsIdentity(_token) _context = identity.Impersonate() Catch ex As Exception Trace.WriteLine(ex) End Try End Sub <PermissionSetAttribute(SecurityAction.Demand, Name:="FullTrust")> _ Public Sub Leave() If Not Me.InContext Then Return _context.Undo() If _token <> IntPtr.Zero Then CloseHandle(_token) _context = Nothing End Sub End Class
Pour l'utiliser, il suffit d'appeler Enter au début de la section de code qui doit être exécutée sous un autre nom d'utilisateur et d'appeler Leave à la fin :
Dim ctx As New WrapperImpersonationContext(domain, user, password) ctx.Enter() ' Le code s'exécute sous le nom de user ctx.Leave() ' On revient avec le nom de l'utilisateur qui a lancé le programme
Besoin d'un développeur ? Contactez nous
Réactivité, coûts modérés.
Maxence DELANNOY - maxence.delannoy@wiip.fr - Tél. : 09.70.46.32.55
|
Add new comment