#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