2010-12-22 21 views
7

Me gustaría suplantar a un usuario específico en el código para realizar alguna manipulación de archivos en una máquina remota. El problema que tengo es que no puedo hacer que la suplantación funcione. Estoy usando el código del artículo de Microsoft que se encuentra aquí: How to implement impersonation in an ASP.NET applicationSuplantar usuario en código subyacente

Me gustaría obtener instrucciones sobre cómo y dónde iniciar el proceso de depuración. Aquí están mis archivos:

Test.aspx:

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Test.aspx.vb" Inherits="TraceFile_Test" %> 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 

<html xmlns="http://www.w3.org/1999/xhtml"> 
<head runat="server"> 
    <title></title> 
</head> 
<body> 
    <form id="form1" runat="server"> 
    <div> 
    This is the test page!<br /> 
    <br /> 
    Result: <asp:Label ID="lblResult" runat="server"></asp:Label><br /> 
    <br /> 
    <asp:Button ID="btnRunTest" Text="Run Test" runat="server" /> 
    </div> 
    </form> 
</body> 
</html> 

Test.aspx.vb:

Imports System.Web 
Imports System.Web.Security 
Imports System.Security.Principal 
Imports System.Runtime.InteropServices 

Partial Class TraceFile_Test 
    Inherits System.Web.UI.Page 


    Dim LOGON32_LOGON_INTERACTIVE As Integer = 2 
    Dim LOGON32_PROVIDER_DEFAULT As Integer = 0 

    Dim impersonationContext As WindowsImpersonationContext 

    Declare Function LogonUserA 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 Integer 

    Declare Auto Function DuplicateToken Lib "advapi32.dll" (_ 
          ByVal ExistingTokenHandle As IntPtr, _ 
          ByVal ImpersonationLevel As Integer, _ 
          ByRef DuplicateTokenHandle As IntPtr) As Integer 

    Declare Auto Function RevertToSelf Lib "advapi32.dll"() As Long 
    Declare Auto Function CloseHandle Lib "kernel32.dll" (ByVal handle As IntPtr) As Long 


    Public Sub Page_Load(ByVal s As Object, ByVal e As EventArgs) 
     lblResult.Text = "Hit button to run test, please." 
    End Sub 

    Private Function impersonateValidUser(ByVal userName As String, _ 
    ByVal domain As String, ByVal password As String) As Boolean 

     Dim tempWindowsIdentity As WindowsIdentity 
     Dim token As IntPtr = IntPtr.Zero 
     Dim tokenDuplicate As IntPtr = IntPtr.Zero 
     impersonateValidUser = False 

     If RevertToSelf() Then 
      If LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, token) <> 0 Then 
       If DuplicateToken(token, 2, tokenDuplicate) <> 0 Then 
        tempWindowsIdentity = New WindowsIdentity(tokenDuplicate) 
        impersonationContext = tempWindowsIdentity.Impersonate() 
        If Not impersonationContext Is Nothing Then 
         impersonateValidUser = True 
        End If 
       End If 
      End If 
     End If 
     If Not tokenDuplicate.Equals(IntPtr.Zero) Then 
      CloseHandle(tokenDuplicate) 
     End If 
     If Not token.Equals(IntPtr.Zero) Then 
      CloseHandle(token) 
     End If 
    End Function 

    Private Sub undoImpersonation() 
     impersonationContext.Undo() 
    End Sub 


    Protected Sub btnRunTest_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnRunTest.Click 
     If impersonateValidUser("myUserName", "myDomain", "myPassword") Then 
      'Insert your code that runs under the security context of a specific user here. 
      Trace.Write("impersonation successful!") 
      lblResult.Text = "success" 
      undoImpersonation() 
     Else 
      'Your impersonation failed. Therefore, include a fail-safe mechanism here. 
      Trace.Write("impersonation failed!") 
      lblResult.Text = "fail" 
     End If 
    End Sub 
End Class 

Substituí credenciales reales con miNombreUsuario, miDominio, y para el miContraseña enviar.

El servidor web es un servidor de Windows 2008 que ejecuta IIS 7. No soy un tipo servidor, por lo que no sé dónde estar el proceso de solución de problemas. Es el problema con el código o el lado del servidor?

Como siempre, ¡gracias de antemano por tomarse el tiempo para ayudar!

+0

¿Hay una excepción no controlada tirado o se acaba de fallar? ¿Algo en los registros de eventos? – kd7

+0

+100 puntos de confusión para mezclar las importaciones de funciones DLL con VB. ¿Has probado ** ** C#? –

+0

¿ha tenido la oportunidad de verificar mi respuesta? Tengo curiosidad si funcionará para ti. – Peter

Respuesta

9

Aquí está el código que estoy usando en producción.

En primer lugar la clase, muy similar a la suya:

Imports System.Security.Principal 
Imports System.Security.Permissions 
Imports System.Diagnostics 
Imports System.Runtime.InteropServices 
Imports System.Security 

Public Class LogonAPI 
    Public Const SECURITY_IMPERSONATION_LEVEL_SecurityAnonymous As Integer = 0 
    Public Const SECURITY_IMPERSONATION_LEVEL_SecurityIdentification As Integer = 1 
    Public Const SECURITY_IMPERSONATION_LEVEL_SecurityImpersonation As Integer = 2 
    Public Const SECURITY_IMPERSONATION_LEVEL_SecurityDelegation As Integer = 3 

    Public Const LOGON32_PROVIDER_DEFAULT As Integer = 0 
    Public Const LOGON32_PROVIDER_WINNT35 As Integer = 1 
    Public Const LOGON32_PROVIDER_WINNT40 As Integer = 2 
    Public Const LOGON32_PROVIDER_WINNT50 As Integer = 3 

    Public Const LOGON32_LOGON_INTERACTIVE As Integer = 2 
    Public Const LOGON32_LOGON_NETWORK As Integer = 3 
    Public Const LOGON32_LOGON_BATCH As Integer = 4 
    Public Const LOGON32_LOGON_SERVICE As Integer = 5 
    Public Const LOGON32_LOGON_UNLOCK As Integer = 7 
    Public Const LOGON32_LOGON_NETWORK_CLEARTEXT As Integer = 8 
    Public Const LOGON32_LOGON_NEW_CREDENTIALS As Integer = 9 

    Public Const ERROR_LOGON_FAILURE As Integer = 1326 

    <DllImport("advapi32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _ 
    Public Shared Function LogonUser(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 
    End Function 

    <DllImport("advapi32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _ 
    Public Shared Function RevertToSelf() As Boolean 
    End Function 

    <DllImport("kernel32.dll", CharSet:=CharSet.Auto)> _ 
    Public Shared Function CloseHandle(ByVal handle As IntPtr) As Boolean 
    End Function 

    <DllImport("advapi32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _ 
    Public Shared Function DuplicateToken(ByVal hToken As IntPtr, ByVal impersonationLevel As Integer, ByRef hNewToken As IntPtr) As Integer 
    End Function 

    Public Shared Function Login(ByVal Username As String, ByVal Domain As String, ByVal Password As String) As WindowsIdentity 
     Dim secPerm As New SecurityPermission(SecurityPermissionFlag.UnmanagedCode) 
     secPerm.Assert() 

     Dim user As WindowsIdentity = Nothing 

     Dim refToken As IntPtr = IntPtr.Zero 
     Dim loggedIn As Boolean 

     loggedIn = LogonAPI.LogonUser(Username, Domain, Password, LogonAPI.LOGON32_LOGON_NETWORK_CLEARTEXT, LogonAPI.LOGON32_PROVIDER_DEFAULT, refToken) 

     If loggedIn = True Then 
      user = New WindowsIdentity(refToken, "NTLM", WindowsAccountType.Normal, True) 
     End If 
     CodeAccessPermission.RevertAssert() 

     Return user 
    End Function 
End Class 

lo prueba llamando al:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load 
    Dim ident As WindowsIdentity = LogonAPI.Login("user", "Domain", "password") 

    Dim imp = ident.Impersonate() 

    'impersonation code 
    Response.Write("Impersonating") 

    imp.Undo() 
End Sub 
+0

No sé por qué no vi la respuesta en mi bandeja de entrada. Perdón por el retraso. – zeroef

+0

Necesitaba recibir un archivo en una aplicación web y subirlo a una carpeta compartida que requería autenticación. Esta clase funcionó bastante bien. – ASalazar

Cuestiones relacionadas