我需要在 VB.NET 2008 WinForms 应用程序中“模拟”一个用户,以便该应用程序可以接受 PC 上任何用户的 Active Directory 登录,而不管谁实际登录到 Windows。我希望应用程序的 My.User 成为登录应用程序的人的 AD 帐户。我使用以下代码成功地做到了这一点:
Private 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 Boolean
Const LOGON32_LOGON_INTERACTIVE As Long = 2
Const LOGON32_LOGON_NETWORK As Long = 3
Const LOGON32_PROVIDER_DEFAULT As Long = 0
Const LOGON32_PROVIDER_WINNT35 As Long = 1
Const LOGON32_PROVIDER_WINNT40 As Long = 2
Const LOGON32_PROVIDER_WINNT50 As Long = 3
' Influenced from the example at http://aspalliance.com/39
Public Shared Function Login(ByVal uid As String, ByVal pwd As String) As Boolean
' Get the user's domain name.
Dim domainName As String = My.User.Name.Substring(0, My.User.Name.IndexOf("\"))
' This token is returned by the LogonUser API call (variable is passed ByRef).
Dim token As IntPtr
If LogonUser(uid, domainName, pwd, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, token) Then
' Added this line per response to this question:
WindowsIdentity.Impersonate(token)
' If the login succeeds, then impersonate that user by changing CurrentPrincipal.
Dim wi As New Principal.WindowsIdentity(token)
Dim wp As New Principal.WindowsPrincipal(wi)
My.User.CurrentPrincipal = wp
Return True
Else
Return False
End If
End Function
但是,该应用程序使用带有连接到 SQL Server 2000 的数据访问层的 .DLL。在连接字符串中使用“Integrated Security=SSPI”的 SQL Server 似乎正在接收登录到 Windows 的帐户的登录信息而不是帐户返回 My.User.CurrentPrincipal.Identity,在单步执行代码时,在 WinForms 应用程序代码和 .DLL 的应用程序代码中。
WinForms 应用程序和 .DLL 代码都正确地将 My.User.CurrentPrincipal.Identity 识别为登录到应用程序的帐户,而不是 Windows。它只是没有传播到 SQL Server。这可以通过将 SUSER_SNAME() 写入 T-SQL 中表的列的存储过程来证明。
谁能看到我出了什么问题?
编辑:我已经WindowsIdentity.Impersonate(token)
按照说明添加了该行,但是现在当我的 .DLL 尝试创建 SQL Server 连接时,它会引发此错误:
用户“NT AUTHORITY\ANONYMOUS LOGON”登录失败。