Change impersonation in ASP.NET
7
fracturedpsyche
This class allows the developer to change the current impersonated user. This is not my code originally, so I cannot take credit for it. I thought it may be useful to someone so I am posting it here.
#Region "Imports Statements"
Imports System.Runtime.InteropServices
Imports System.Security.Principal
Imports System.Security.Permissions
#End Region
#Region "Enumerations"
''' <summary>
''' The type of logon to use for logon.
''' </summary>
''' <remarks></remarks>
Public Enum LogonType As Integer
LOGON32_LOGON_INTERACTIVE = 2
LOGON32_LOGON_NETWORK = 3
LOGON32_LOGON_BATCH = 4
LOGON32_LOGON_SERVICE = 5
LOGON32_LOGON_UNLOCK = 7
LOGON32_LOGON_NETWORK_CLEARTEXT = 8 'Only for Win2K or higher
LOGON32_LOGON_NEW_CREDENTIALS = 9 'Only for Win2K or higher
End Enum
''' <summary>
''' The logon provider to use for logon.
''' </summary>
''' <remarks></remarks>
Public Enum LogonProvider As Integer
LOGON32_PROVIDER_DEFAULT = 0
LOGON32_PROVIDER_WINNT35 = 1
LOGON32_PROVIDER_WINNT40 = 2
LOGON32_PROVIDER_WINNT50 = 3
End Enum
#End Region
#Region "Utility Classes"
''' <summary>
''' This class wraps several unmanaged Window's security and authentication functions so they can be called from .NET managed code.
''' </summary>
''' <remarks></remarks>
Class SecuUtil32
#Region "Methods"
''' <summary>
''' This function wraps the LogonUser function found in 'advapi32.dll'. This function
''' will attempt to logon the specified user to the specified domain."
''' </summary>
''' <param name="lpszUserName">The Window's username that will be used to authenticate.</param>
''' <param name="lpszDomain">The domain that will be used to authenticate.</param>
''' <param name="lpszPassword">The password that will be used to authenticate.</param>
''' <param name="dwLogonLype">The type of logon that will be used.</param>
''' <param name="dwLogonProvider">The logon provider that will be used.</param>
''' <param name="TokenHandle">The token handle that will be used.</param>
''' <returns></returns>
''' <remarks></remarks>
<DllImport("advapi32.dll", SetLastError:=True)> _
Public Shared Function LogonUser(ByVal lpszUserName As String, _
ByVal lpszDomain As String, _
ByVal lpszPassword As String, _
ByVal dwLogonLype As Integer, _
ByVal dwLogonProvider As Integer, _
ByRef TokenHandle As IntPtr) As Boolean
End Function
''' <summary>
''' This function wraps the CloseHandle function found in 'kernel32.dll'. This function will attempt to
''' close the token handle used for authentication."
''' </summary>
''' <param name="handle">The token handle to close.</param>
''' <returns></returns>
''' <remarks></remarks>
<DllImport("kernel32.dll", CharSet:=CharSet.Auto)> _
Public Shared Function CloseHandle(ByVal handle As IntPtr) As Boolean
End Function
''' <summary>
''' This function wraps the DuplicateToken function found in 'advapi32.dll'. This function will
''' attempt to duplicate the token handle used for authentication.
''' </summary>
''' <param name="ExistingTokenHandle">The token handle to be duplicated.</param>
''' <param name="SECURITY_IMPERSONATION_LEVEL"></param>
''' <param name="DuplicateTokenHandle">The new token created by duplicating the existing token.</param>
''' <returns></returns>
''' <remarks></remarks>
<DllImport("advapi32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Public Shared Function DuplicateToken(ByVal ExistingTokenHandle As IntPtr, _
ByVal SECURITY_IMPERSONATION_LEVEL As Integer, _
ByRef DuplicateTokenHandle As IntPtr) As Boolean
End Function
#End Region
End Class
#End Region
#Region "NetworkSecurity Class"
''' <summary>
''' This function allows web applications to dynamically impersonate a user by calling the
''' 'Impersonate User' function and passing the required information.
''' </summary>
''' <remarks></remarks>
Public Class NetworkSecurity
#Region "Constants"
Const securityImpersonation As Integer = 2
#End Region
#Region "Construction"
Public Sub New()
End Sub
#End Region
#Region "Public Methods"
''' <summary>
''' This function will attempt to impersonate a specified user.
''' </summary>
''' <param name="domain">The domain to attempt to logon to.</param>
''' <param name="login">The username to use for authentication.</param>
''' <param name="password">The password to use for authentication.</param>
''' <param name="logonType">The type of logon to use.</param>
''' <param name="logonProvider">The logon provider to use.</param>
''' <returns></returns>
''' <remarks></remarks>
Public Function ImpersonateUser(ByVal domain As String, _
ByVal login As String, _
ByVal password As String, _
ByVal logonType As LogonType, _
ByVal logonProvider As LogonProvider) As WindowsImpersonationContext
Dim tokenHandle As New IntPtr(0)
Dim duplicateTokenHandle As New IntPtr(0)
Try
tokenHandle = IntPtr.Zero
duplicateTokenHandle = IntPtr.Zero
'Call LogonUser to obtain a handle to an access token
Dim returnValue As Boolean = SecuUtil32.LogonUser(login, domain, password, CInt(logonType), CInt(logonProvider), tokenHandle)
If (returnValue = False) Then
Dim ret As Integer = Marshal.GetLastWin32Error()
Dim err As String = String.Format("LogonUser failed with error code: {0}", ret)
Throw New ApplicationException(err, Nothing)
End If
returnValue = SecuUtil32.DuplicateToken(tokenHandle, securityImpersonation, duplicateTokenHandle)
If (returnValue = False) Then
SecuUtil32.CloseHandle(tokenHandle)
Throw New ApplicationException("Failed to duplicate token", Nothing)
End If
Dim newID As New WindowsIdentity(duplicateTokenHandle)
Dim impersonatedUser As WindowsImpersonationContext = newID.Impersonate()
Return impersonatedUser
Catch ex As Exception
Throw New ApplicationException(ex.Message, ex)
End Try
Return Nothing
End Function
#End Region
End Class
#End Region






There are currently no comments for this snippet.