冒充只有在當前用戶我們有我們整個多個web應用程序使用的一些常用方法類庫,我們正與我們的Impersonation
類的問題。在每個單獨的應用程序中使用LogonUser進行模擬時,Environment.UserName
會返回正在使用該應用程序的用戶。但是當我們在使用block的類庫模擬中調用它時,它將作爲AppPool標識返回。程序池的身份,而不是從類庫(DLL)
返回客戶端的用戶名:
Declare 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 Integer
If (LogonUser(Config.AdminUser, Config.AdminDomain, Config.AdminPassword, 9, 0, token) <> 0) Then
Dim newIdentity As WindowsIdentity = New WindowsIdentity(token)
Using impersonatedUser As WindowsImpersonationContext = newIdentity.Impersonate()
name = Environment.UserName
End Using
End If
返回應用程序池的用戶名:
Imports Class.Library
Using admin As New Impersonation
name = Environment.UserName
End Using
HttpContext.Current.User.Identity.Name
彷彿回到我們正在尋找的用戶名,但我們看不出爲什麼Environment.UserName
有效地工作在服務器上,但僅限於它不使用我們的自定義類庫的dll參考。下面來看看在我們的模擬類:
Public Class Impersonation : Implements IDisposable
Private impersonationContext As WindowsImpersonationContext = Nothing
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 Integer
Declare Auto Function RevertToSelf Lib "advapi32.dll"() As Boolean
Declare Auto Function CloseHandle Lib "kernel32.dll" (ByVal handle As IntPtr) As Boolean
Declare Auto Function DuplicateToken Lib "advapi32.dll" (ByVal hToken As IntPtr, ByVal impersonationLevel As Integer, ByRef hNewToken As IntPtr) As Integer
Private Shared newIdentity As WindowsIdentity
Private Shared token As New IntPtr(0)
Public Sub New(Optional ByVal userName As String = "", Optional ByVal password As String = "", Optional ByVal domainName As String = Config.AdminDomain)
If userName = "" Then
userName = Config.AdminUser
End If
If password = "" Then
password = Config.AdminPassword
End If
Dim logonType As Integer = 9
impersonationContext = ImpersonateUser(userName, domainName, password, logonType)
End Sub
Private Sub Undo()
If impersonationContext IsNot Nothing Then
impersonationContext.Undo()
End If
End Sub
Private Shared Function ImpersonateUser(ByVal userName As String, ByVal domain As String, ByVal password As String, ByVal logonType As Integer) As WindowsImpersonationContext
Dim res As WindowsImpersonationContext = Nothing
Dim tempWindowsIdentity As WindowsIdentity = Nothing
Dim token As IntPtr = IntPtr.Zero
Dim tokenDuplicate As IntPtr = IntPtr.Zero
Try
If (RevertToSelf()) Then
If LogonUser(userName, domain, password, logonType, 0, token) Then
If DuplicateToken(token, 2, tokenDuplicate) <> 0 Then
tempWindowsIdentity = New WindowsIdentity(tokenDuplicate)
Return tempWindowsIdentity.Impersonate()
Else
Throw New Win32Exception(Marshal.GetLastWin32Error())
End If
Else
Throw New Win32Exception(Marshal.GetLastWin32Error())
End If
Else
Throw New Win32Exception(Marshal.GetLastWin32Error())
End If
Finally
If token <> IntPtr.Zero Then
CloseHandle(token)
End If
If tokenDuplicate <> IntPtr.Zero Then
CloseHandle(tokenDuplicate)
End If
End Try
Return res
End Function
Private disposedValue As Boolean = False
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If Not Me.disposedValue Then
Undo()
End If
Me.disposedValue = True
End Sub
Public Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
End Class
我有一種感覺,它是與該DLL文件在服務器上,當我們使用using塊,Environment.UserName
會從其中過程的用戶名正在服務器上運行。但我不明白爲什麼它會在最初使用模擬的方法中創建New WindowsIdentity()
而不是當我們從dll引用它時因爲它們都在服務器上運行。
實質上,HttpContext.Current.User.Identity.Name
已成爲我們在本地運行事件並嘗試調試出現的問題時的問題。我們希望,1.爲什麼這是爲了知識目的而發生的答案,以及2.如果它們的偶數超出HttpContext.Current.User.Identity.Name
的任何一個可能的解決方案。 (在VB或者C#的答案,歡迎。)