|
Besoin d'un développeur C#/VB/.NET ? Contactez nous
Réactivité, coûts modérés.
Maxence DELANNOY - Tél. : 09.70.46.32.55
|
|
Soumis par Maxence le jeu, 29/07/2010 - 12:31
.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 ClassPour 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


Poster un nouveau commentaire