Можно ли дублировать следующий процесс учетных данных в VB.NET? - PullRequest
3 голосов
/ 04 мая 2009

Решение (своего рода):

Оказывается, что олицетворение с безопасностью .NET разрешает доступ только на уровне приложений. Поскольку COM-объект находится на системном уровне, олицетворенный пользователь все еще не может создать его экземпляр. Я понял это, щелкнув правой кнопкой мыши по исполняемому файлу и выбрав «Run As ...», программа работала нормально. Я обнаружил, что запускает программу с доступом к системе (при условии, что у пользователя, с которым вы ее запускаете, есть эти учетные данные). Сейчас я нахожусь в процессе создания внешней программы, которая запустит это приложение, используя этот метод.

Спасибо за советы: D


У меня установлена ​​Windows XP на виртуальной машине. Это часть моего домена, но вошедший в систему пользователь является локальным пользователем. Очевидно, что если я попытаюсь получить доступ к общему сетевому ресурсу, он запросит имя пользователя / пароль:

alt text

Программа, которую я тестирую на виртуальной машине, использует 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

Ответы [ 3 ]

1 голос
/ 05 июня 2009

Я сталкивался с этим раньше и использовал два разных решения - самое простое - использовать стороннее приложение: 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
0 голосов
/ 07 мая 2009

Я делаю то же самое, чтобы сопоставить сетевые диски для копирования файлов между компьютерами. Я не писал код, но он почти такой же, как ваш, за исключением двух вещей:

  • После возвращения метода 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
0 голосов
/ 05 мая 2009

С вашими определениями я использую

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

в моем коде, который проходит аутентификацию в сети. Я выдаю себя за локального пользователя на удаленном компьютере, как и вы. Однако это было так давно, что я не помню обоснования для использования этих значений.

...