3

解决方案(有点):

事实证明,这种具有 .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
4

3 回答 3

1

我之前遇到过这种情况,并使用了两种不同的解决方案 - 最简单的是使用第三方应用程序:TqcRunas:http ://www.quimeras.com/Products/products.asp ,它允许您将所需的凭据打包成加密的文件。但是,如果密码被迫过期,那就很痛苦了。

我使用的另一个解决方案是使用替代凭据调用新进程:

        Dim myProcessStartInfo As ProcessStartInfo = New ProcessStartInfo

    With myProcessStartInfo

        .FileName = "file path and name"

        .Domain = "domainname"
        .UserName = "username"

        'password needs to be a SerureString
        Using NewPassword As New Security.SecureString
            With NewPassword
                For Each c As Char In "password".ToCharArray
                    .AppendChar(c)
                Next c
                .MakeReadOnly()
            End With
            .Password = NewPassword.Copy
        End Using

        'UseShellExecute must be false for impersonated process
        .UseShellExecute = False

    End With

    Using Process As New System.Diagnostics.Process
        With Process
            .StartInfo = myProcessStartInfo
            .Start()
        End With
    End Using
于 2009-06-05T05:06:40.553 回答
0

根据您的定义,我使用

LogonUser(_username, _domainname, _password, LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_WINNT50, _tokenHandle)

在我通过网络进行身份验证的代码中。我正在模拟远程机器上的本地用户,就像你一样。然而,这是很久以前的事了,我不记得使用这些值的理由。

于 2009-05-04T21:08:57.400 回答
0

我做了类似的事情来映射网络驱动器以在机器之间复制文件。我没有写代码,但它和你的几乎一样,除了两件事:

  • 在 Impersonate 方法返回后,我使用 CloseHandle 例程关闭两个标记,然后退出我的模拟方法。

  • 在模仿者的顶部发生的第一件事是调用 RevertToSelf,大概是为了取消任何以前的模仿。

我不知道他们是否会有所作为,但值得一试。以下是相关声明:

Declare Auto Function CloseHandle Lib "kernel32.dll" (ByVal handle As IntPtr) As Long
Declare Auto Function RevertToSelf Lib "advapi32.dll" () As Long
于 2009-05-07T02:28:44.150 回答