É possível duplicar o seguinte processo credencial em VB.NET?
-
03-07-2019 - |
Pergunta
Solution (kinda):
Acontece que esta representação com a segurança do .NET só permite o acesso em nível de aplicativo. Desde o objeto COM é no nível do sistema, o usuário representado ainda não pode instanciá-lo. Eu descobri isso clicando com o executável e selecionando "Executar como ...", o programa funcionou bem. Eu descobri que inicia o programa com acesso ao sistema (assumindo que o usuário que você está executando-o com tem essas credenciais). Agora eu estou no processo de criação de um programa externo que vai lançar este aplicativo utilizando este método.
Obrigado pelas dicas: D
Eu tenho uma instalação do Windows XP em uma máquina virtual. Faz parte do meu domínio, mas o usuário conectado é de apenas um usuário local. Obviamente, se eu tentar acessar um compartilhamento de rede que irá pedir para um usuário / senha:
O programa que eu estou testando a máquina virtual usa um objeto COM para a interface com os dados de outro programa. Se eu não fizer impersonate, eu recebo erros, porque eu não tenho as credenciais adequadas.
Eu fiz alguma pesquisa sobre o assunto e encontrou uma série de sites que tinham uma quantidade razoável de informações VB.NET. O problema que estou tendo com o código que eu escrevi é que eu posso acessar os recursos de rede, mas não posso instanciar o objeto COM.
Se eu preencher e enviar o solicitação de credenciais (acima) antes de tentar instanciar-lo, ele funciona bem. Que me leva a crer que deve haver algo que a solicitação de credenciais WinXP está fazendo que eu não sou. Abaixo está o código que estou usando para representação:
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
Eu também tentei enviar diferentes bandeiras para o método imitador, mas nada parece estar funcionando. Aqui estão as diferentes bandeiras que encontrei:
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
Solução
Eu tenho que correr para isso antes, e usou dois soloution diferente - o mais fácil estava usando um aplicativo de terceiros: TqcRunas: http://www.quimeras.com/Products/products.asp que lhe permite empacotar os creentials necessários em um arquivo criptografado. No entanto é uma dor se a senha é forçado a expirar.
A outra solução que eu usei é chamar um novo processo com credenciais alternativas:
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
Outras dicas
Com as definições, eu uso
LogonUser(_username, _domainname, _password, LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_WINNT50, _tokenHandle)
no meu código que está autenticando através da rede. Estou a representar um utilizador local no caixa remoto, como você é. Foi há muito tempo que eu não me lembro a razão para a utilização desses valores, no entanto.
I fazer uma coisa semelhante para mapear unidades de rede para copiar arquivos entre máquinas. Eu não escrever o código, mas é praticamente a mesma que a sua, exceto por duas coisas:
-
Depois dos retornos método personificar Eu fecho ambas as fichas utilizando a rotina CloseHandle, antes de eu sair do meu método imitador.
-
No topo do imitador a primeira coisa que acontece é uma chamada para RevertToSelf, presumivelmente para cancelar qualquer representação anterior.
Eu não sei se eles iriam fazer a diferença, mas vale a pena uma tentativa. Estas foram as declarações relevantes:
Declare Auto Function CloseHandle Lib "kernel32.dll" (ByVal handle As IntPtr) As Long
Declare Auto Function RevertToSelf Lib "advapi32.dll" () As Long