2015-10-15 23 views
0

冒充只有在當前用戶我們有我們整個多個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#的答案,歡迎。)

回答

0

我解決我的問題,在我的類庫創建一個新的方法:如果代碼在服務器上運行

Public Shared Function Current() As String 
    If Not HttpContext.Current.Request.IsLocal Then 
     Dim id As String = HttpContext.Current.User.Identity.Name 
     Return id.Substring(4) 
    Else 
     Return Environment.UserName 
    End If 
End Function 

,它使用HttpContext拉域\用戶名。然後,我substringed出域(我們的域名只有三個字符)。

如果是在本地運行,我回Environment.UserName 我通過簡單地引用的類和方法(Employees.Current

打電話給我的web應用程序中的這個字符串
相關問題