解决方案(有点):
事实证明,这种具有 .NET 安全性的模拟只允许应用程序级别的访问。由于 COM 对象处于系统级别,因此模拟用户仍然无法实例化它。我通过右键单击可执行文件并选择“运行方式...”来解决这个问题,程序运行良好。我发现启动具有系统访问权限的程序(假设您正在运行它的用户具有这些凭据)。现在我正在创建一个外部程序,它将使用这种方法启动这个应用程序。
感谢您的提示:D
我在虚拟机上安装了 Windows XP。它是我域的一部分,但登录用户只是本地用户。显然,如果我尝试访问网络共享,它会提示输入用户/密码:
我在虚拟机上测试的程序使用 COM 对象与来自另一个程序的数据进行交互。如果我不冒充,我会收到错误,因为我没有正确的凭据。
我对此事进行了一些研究,发现许多网站都有大量的 VB.NET 信息。我编写的代码遇到的问题是我可以访问网络资源,但我无法实例化 COM 对象。
如果我在尝试实例化之前填写并提交凭据提示(上图),它可以正常工作。这让我相信 WinXP 凭据提示一定有一些我没有做的事情。以下是我用于模拟的代码:
Public Sub BeginImpersonation()
Const LOGON32_PROVIDER_DEFAULT As Integer = 0
Const LOGON32_LOGON_INTERACTIVE As Integer = 2
Const SecurityImpersonation As Integer = 2
Dim win32ErrorNumber As Integer
_tokenHandle = IntPtr.Zero
_dupeTokenHandle = IntPtr.Zero
If Not LogonUser(_username, _domainname, _password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, _tokenHandle) Then
win32ErrorNumber = System.Runtime.InteropServices.Marshal.GetLastWin32Error()
Throw New ImpersonationException(win32ErrorNumber, GetErrorMessage(win32ErrorNumber), _username, _domainname)
End If
If Not DuplicateToken(_tokenHandle, SecurityImpersonation, _dupeTokenHandle) Then
win32ErrorNumber = System.Runtime.InteropServices.Marshal.GetLastWin32Error()
CloseHandle(_tokenHandle)
Throw New ImpersonationException(win32ErrorNumber, "Unable to duplicate token!", _username, _domainname)
End If
Dim newId As New System.Security.Principal.WindowsIdentity(_dupeTokenHandle)
_impersonatedUser = newId.Impersonate()
_impersonating = True
End Sub
我也尝试向模拟方法发送不同的标志,但似乎没有任何效果。以下是我发现的不同标志:
Enum LOGON32_LOGON
INTERACTIVE = 2
NETWORK = 3
BATCH = 4
SERVICE = 5
UNLOCK = 7
NETWORK_CLEARTEXT = 8
NEW_CREDENTIALS = 9
End Enum
Enum LOGON32_PROVIDER
[DEFAULT] = 0
WINNT35 = 1
WINNT40 = 2
WINNT50 = 3
End Enum
Enum SECURITY_LEVEL
Anonymous = 0
Identification = 1
Impersonation = 2
Delegation = 3
End Enum