Impersonation Class
May 18th, 2007
In today’s business environment more and more companies are securing the PC’s of many employees to prevent damage to their systems via malware downloaded over the Internet or user mistakes. On web servers running publicly available web services, administrators wisely don’t want to expose resources to just anyone. However, as we develop software we may find it necessary to access forbidden resources like certain areas of the registry or a file store on a network server. How can we do this and still keep the application and the system secure? Fortunately, we can use impersonation to solve this problem.
The code below is a simple class I wrote for this purpose. The class is declared as a Friend class rather than Public to avoid any accidential exposure to outside processes. The New method is overloaded so that an unintialized instance can be created as well as one that has credentials passed into it. The empty new method also allows easy subclassing so that other methods for initialization could be added as desired. Impersonation is started in the StartImpersonation method. EndImpersonation ends the session and the Finalize method helps insure that impersonation is ended when the instance is destroyed. The current state of impersonation can be checked in the ImpersonationActive read-only property.
This method is not without risks. First of all, the complete user login credentials have to be passed in as clear text. This means that you will need to use some type of encryption to protect this information at the very least. To protect these credentials further you may want to look into using secure strings.
ยป Click here to download VB.NET source code for this article or view it below.
Imports Microsoft.VisualBasic Imports System.Web Imports System.Web.Security Imports System.Security.Principal Imports System.Runtime.InteropServices ”’ <summary> ”’ Provides impersonation to allow access to resources ”’ </summary> ”’ <remarks></remarks> Friend Class Impersonate Private LOGON32_LOGON_INTERACTIVE As Integer = 2 Private LOGON32_PROVIDER_DEFAULT As Integer = 0 Private impersonationContext As WindowsImpersonationContext Private Declare Function LogonUserA 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 Integer Private Declare Auto Function DuplicateToken Lib “advapi32.dll” ( _ ByVal ExistingTokenHandle As IntPtr, _ ByVal ImpersonationLevel As Integer, _ ByRef DuplicateTokenHandle As IntPtr) As Integer Private Declare Auto Function RevertToSelf Lib “advapi32.dll” () As Long Private Declare Auto Function CloseHandle Lib “kernel32.dll” (ByVal handle As IntPtr) As Long Private _impersonationActive As Boolean ”’ <summary> ”’ Allows creation of a new instance without starting impersonation ”’ </summary> ”’ <remarks></remarks> Public Sub New() End Sub ”’ <summary> ”’ starts impersonation with specified parameters ”’ </summary> ”’ <param name=”userName”>username to impersonate</param> ”’ <param name=”domain”>domain for user</param> ”’ <param name=”password”>password for user</param> ”’ <remarks></remarks> Public Sub New(ByVal userName As String, ByVal domain As String, ByVal password As String) StartImpersonation(userName, domain, password) End Sub ”’ <summary> ”’ starts impersonation with specified parameters ”’ </summary> ”’ <param name=”userName”>username to impersonate</param> ”’ <param name=”domain”>domain for user</param> ”’ <param name=”password”>password for user</param> ”’ <remarks></remarks> Public Function StartImpersonation(ByVal userName As String, ByVal domain As String, ByVal password As String) As Boolean Dim ReturnValue As Boolean = False Dim tempWindowsIdentity As WindowsIdentity Dim token As IntPtr = IntPtr.Zero Dim tokenDuplicate As IntPtr = IntPtr.Zero StartImpersonation = False If CBool(RevertToSelf()) Then If LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, token) <> 0 Then If DuplicateToken(token, 2, tokenDuplicate) <> 0 Then tempWindowsIdentity = New WindowsIdentity(tokenDuplicate) impersonationContext = tempWindowsIdentity.Impersonate() If Not impersonationContext Is Nothing Then ReturnValue = True _impersonationActive = True End If End If End If End If If Not tokenDuplicate.Equals(IntPtr.Zero) Then CloseHandle(tokenDuplicate) End If If Not token.Equals(IntPtr.Zero) Then CloseHandle(token) End If Return ReturnValue End Function ”’ <summary> ”’ Ends impersonation session and returns thread back to original user ”’ </summary> ”’ <remarks></remarks> Public Sub EndImpersonation() impersonationContext.Undo() _impersonationActive = False End Sub Protected Overrides Sub Finalize() If _impersonationActive Then impersonationContext.Undo() _impersonationActive = False End If MyBase.Finalize() End Sub Public ReadOnly Property ImpersonationActive() As Boolean Get Return _impersonationActive End Get End Property End Class
Entry Filed under: Code Examples
Rate This Article:










Leave a Comment
Some HTML allowed:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>
Trackback this post | Subscribe to the comments via RSS Feed