Estás trabajando sin conexión, espera a que vuelva la conexión a Internet

Cómo implementar la suplantación en una aplicación ASP.NET

Este artículo hace referencia a los siguientes espacios de nombres de la Biblioteca de clases de Microsoft .NET Framework:
  • System.Web.Security
  • System.Security.Principal
  • System.Runtime.InteropServices
Resumen
Este artículo describe diferentes maneras de implementar la suplantación en una aplicación ASP.NET.
Más información
Si desea suplantar a un usuario en un subproceso de ASP.NET, puede utilizar alguno de los métodos siguientes en función de sus necesidades:
Nota: puede utilizar el código siguiente para determinar con qué usuario se está ejecutando el subproceso:
System.Security.Principal.WindowsIdentity.GetCurrent().Name				

Suplantar la cuenta o el usuario autenticados de IIS

Para suplantar al usuario que se está autenticando en Microsoft Internet Information Services (IIS) en todas las solicitudes de todas las páginas de la aplicación ASP.NET, debe incluir la etiqueta <identity> en el archivo Web.config de esta aplicación y configurar el atributo impersonate en true. Por ejemplo:
<identity impersonate="true" />				
volver al principio

Suplantar a un usuario específico para todas las solicitudes de una aplicación ASP.NET

Para suplantar a un usuario específico para todas las solicitudes de todas las páginas de una aplicación ASP.NET, puede especificar los atributos userName y password en la etiqueta <identity> del archivo Web.config de esa aplicación. Por ejemplo:
<identity impersonate="true" userName="accountname" password="password" />				
Nota: la identidad del proceso que suplanta a un usuario específico en el subproceso debe tener el privilegio "Actuar como parte del sistema operativo". De manera predeterminada, el proceso Aspnet_wp.exe se ejecuta bajo una cuenta de equipo llamada ASPNET. Sin embargo, esta cuenta no tiene los privilegios necesarios para suplantar a un usuario específico. Recibirá un mensaje de error si intenta suplantar a un usuario específico. Esta información solo se aplica a la versión .NET Framework 1.0. Este privilegio no se requiere para.NET Framework 1.1.

Como solución alternativa para este problema, utilice uno de los métodos siguientes:
  • Conceda el privilegio "Actuar como parte del sistema operativo" a la cuenta ASPNET (la cuenta con menos privilegios).

    Nota: aunque puede utilizar este método para solucionar el problema, Microsoft no lo recomienda.
  • Cambie la cuenta que ejecuta el proceso Aspnet_wp.exe en la cuenta Sistema en la sección de configuración <processModel> del archivo Machine.config
volver al principio

Suplantar al usuario que se autentica en el código

Para suplantar al usuario que se autentica (User.Identity) solo cuando se ejecuta una sección concreta de código, puede utilizar el código siguiente. Este método requiere que la identidad del usuario que se autentica sea del tipo WindowsIdentity.

Visual Basic .NET
Dim impersonationContext As System.Security.Principal.WindowsImpersonationContextDim currentWindowsIdentity As System.Security.Principal.WindowsIdentitycurrentWindowsIdentity = CType(User.Identity, System.Security.Principal.WindowsIdentity)impersonationContext = currentWindowsIdentity.Impersonate()'Inserte aquí el código que se ejecuta en el contexto de seguridad del usuario que se autentica.impersonationContext.Undo()				
Visual C# .NET
System.Security.Principal.WindowsImpersonationContext impersonationContext;impersonationContext =     ((System.Security.Principal.WindowsIdentity)User.Identity).Impersonate();//Inserte aquí el código que se ejecuta en el contexto de seguridad del usuario que se autentica.impersonationContext.Undo();				
Visual J# .NET
System.Security.Principal.WindowsImpersonationContext impersonationContext;impersonationContext =     ((System.Security.Principal.WindowsIdentity)get_User().get_Identity()).Impersonate();//Inserte aquí el código que se ejecuta en el contexto de seguridad del usuario que se autentica.impersonationContext.Undo();				
volver al principio

Suplantar a un usuario específico en el código

Para suplantar a un usuario específico solo cuando se ejecuta una sección concreta de código, utilice el código siguiente.

Visual Basic .NET
<%@ Page Language="VB" %><%@ Import Namespace = "System.Web" %><%@ Import Namespace = "System.Web.Security" %><%@ Import Namespace = "System.Security.Principal" %><%@ Import Namespace = "System.Runtime.InteropServices" %><script runat=server>Dim LOGON32_LOGON_INTERACTIVE As Integer = 2Dim LOGON32_PROVIDER_DEFAULT As Integer = 0Dim impersonationContext As WindowsImpersonationContextDeclare 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 IntegerDeclare Auto Function DuplicateToken Lib "advapi32.dll" ( _                        ByVal ExistingTokenHandle As IntPtr, _                        ByVal ImpersonationLevel As Integer, _                        ByRef DuplicateTokenHandle As IntPtr) As IntegerDeclare Auto Function RevertToSelf Lib "advapi32.dll" () As LongDeclare Auto Function CloseHandle Lib "kernel32.dll" (ByVal handle As IntPtr) As LongPublic Sub Page_Load(ByVal s As Object, ByVal e As EventArgs)    If impersonateValidUser("username", "domain", "password") Then        'Inserte aquí el código que se ejecuta en el contexto de seguridad de un usuario específico.        undoImpersonation()    Else        'Error en la suplantación. Por lo tanto, incluya aquí un mecanismo a prueba de errores.    End IfEnd SubPrivate 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 IfEnd FunctionPrivate Sub undoImpersonation()    impersonationContext.Undo()End Sub</script>
Visual C# .NET
<%@ Page Language="C#"%><%@ Import Namespace = "System.Web" %><%@ Import Namespace = "System.Web.Security" %><%@ Import Namespace = "System.Security.Principal" %><%@ Import Namespace = "System.Runtime.InteropServices" %><script runat=server>public const int LOGON32_LOGON_INTERACTIVE = 2;public const int LOGON32_PROVIDER_DEFAULT = 0;WindowsImpersonationContext impersonationContext; [DllImport("advapi32.dll")]public static extern int LogonUserA(String lpszUserName, 	String lpszDomain,	String lpszPassword,	int dwLogonType, 	int dwLogonProvider,	ref IntPtr phToken);[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]public static extern int DuplicateToken(IntPtr hToken, 	int impersonationLevel,  	ref IntPtr hNewToken);                          [DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]public static extern bool RevertToSelf();[DllImport("kernel32.dll", CharSet=CharSet.Auto)]public static extern  bool CloseHandle(IntPtr handle);public void Page_Load(Object s, EventArgs e){	if(impersonateValidUser("username", "domain", "password"))	{		//Inserte aquí el código que se ejecuta en el contexto de seguridad de un usuario específico.		undoImpersonation();	}	else	{		//Error en la suplantación. Por lo tanto, incluya aquí un mecanismo a prueba de errores.	}}private bool impersonateValidUser(String userName, String domain, String password){	WindowsIdentity tempWindowsIdentity;	IntPtr token = IntPtr.Zero;	IntPtr tokenDuplicate = IntPtr.Zero;	if(RevertToSelf())	{		if(LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE, 			LOGON32_PROVIDER_DEFAULT, ref token) != 0)		{			if(DuplicateToken(token, 2, ref tokenDuplicate) != 0) 			{				tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);				impersonationContext = tempWindowsIdentity.Impersonate();				if (impersonationContext != null)				{					CloseHandle(token);					CloseHandle(tokenDuplicate);					return true;				}			}		} 	}	if(token!= IntPtr.Zero)		CloseHandle(token);	if(tokenDuplicate!=IntPtr.Zero)		CloseHandle(tokenDuplicate);	return false;}private void undoImpersonation(){	impersonationContext.Undo();}</script>
Visual J# .NET
<%@ Page language="VJ#" %><%@ Import Namespace="System.Web" %><%@ Import Namespace="System.Web.Security" %><%@ Import Namespace="System.Security.Principal" %><%@ Import Namespace="System.Runtime.InteropServices" %><script runat=server>public static int LOGON32_LOGON_INTERACTIVE = 2;public static int LOGON32_PROVIDER_DEFAULT = 0;WindowsImpersonationContext impersonationContext; /** @attribute DllImport("advapi32.dll") */ public static native int LogonUserA(String lpszUserName, 	String lpszDomain, 	String lpszPassword,	int dwLogonType, 	int dwLogonProvider, 	System.IntPtr[] phToken);/** @attribute DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true) */ public static native int DuplicateToken(System.IntPtr hToken,	int impersonationLevel,	System.IntPtr[] hNewToken);/** @attribute DllImport("kernel32.dll",CharSet=CharSet.Auto) */ public static native  boolean CloseHandle(System.IntPtr[] handle);/** @attribute DllImport("advapi32.dll", 	 CharSet=CharSet.Auto,SetLastError=true) */	 public static native boolean RevertToSelf();public void Page_Load(Object s, System.EventArgs e){	if(impersonateValidUser("username", "domain", "password"))	{		//Inserte aquí el código que se ejecuta en el contexto de seguridad de un usuario específico.		undoImpersonation();	}	else	{		//Error en la suplantación. Por lo tanto, incluya aquí un mecanismo a prueba de errores.	}}private boolean impersonateValidUser(String userName, String domain, String password){	WindowsIdentity tempWindowsIdentity;	System.IntPtr[] token = new System.IntPtr[1];	System.IntPtr[] tokenDuplicate = new System.IntPtr[1];	if(RevertToSelf())	{		if(LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE, 			LOGON32_PROVIDER_DEFAULT, token) != 0)		{			if(DuplicateToken(token[0], 2, tokenDuplicate) != 0) 			{				tempWindowsIdentity = new WindowsIdentity(tokenDuplicate[0]);				impersonationContext = tempWindowsIdentity.Impersonate();				if (impersonationContext != null)				{					CloseHandle(tokenDuplicate);					CloseHandle(token);					return true;				}							}					} 	}	if(!token[0].Equals(System.IntPtr.Zero))		CloseHandle(token);	if(!tokenDuplicate[0].Equals(System.IntPtr.Zero))		CloseHandle(tokenDuplicate);	return false;}private void undoImpersonation(){	impersonationContext.Undo();}</script>				
Nota: la identidad del proceso que suplanta a un usuario específico en el subproceso debe tener el privilegio "Actuar como parte del sistema operativo" si el proceso Aspnet_wp.exe se ejecuta en un equipo basado en Microsoft Windows 2000. El privilegio "Actuar como parte del sistema operativo" no se requiere si el proceso Aspnet_wp.exe se ejecuta en un equipo basado en Windows XP o en un equipo basado en Windows Server 2003. De manera predeterminada, el proceso Aspnet_wp.exe se ejecuta bajo una cuenta de equipo llamada ASPNET. Sin embargo, esta cuenta no tiene los privilegios necesarios para suplantar a un usuario específico. Recibirá un mensaje de error si intenta suplantar a un usuario específico. .

Como solución alternativa para este problema, utilice uno de los métodos siguientes:
  • Conceder el privilegio "Actuar como parte del sistema operativo" a la cuenta ASPNET.

    Nota: no se recomienda este método para solucionar el problema.
  • Cambie la cuenta que ejecuta el proceso Aspnet_wp.exe en la cuenta Sistema en la sección de configuración <processModel> del archivo Machine.config
volver al principio
Referencias
Para obtener información adicional acerca de la seguridad de ASP.NET, haga clic en el número de artículo siguiente para verlo en Microsoft Knowledge Base:
306590 Introducción a la seguridad de ASP.NET
login failed null (null) impersonate
Nota: es un artículo de "PUBLICACIÓN RÁPIDA" creado directamente por la organización de soporte técnico de Microsoft. La información aquí contenida se proporciona como está, como respuesta a problemas que han surgido. Como consecuencia de la rapidez con la que lo hemos puesto disponible, los materiales podrían incluir errores tipográficos y pueden ser revisados en cualquier momento sin previo aviso. Vea las Condiciones de uso para otras consideraciones
Propiedades

Id. de artículo: 306158 - Última revisión: 02/04/2014 14:15:00 - Revisión: 1.0

Microsoft ASP.NET 1.0, Microsoft ASP.NET 1.1, Microsoft Visual Basic .NET 2002 Standard Edition, Microsoft Visual Basic .NET 2003 Standard Edition, Microsoft Visual C# .NET 2002 Standard Edition, Microsoft Visual C# .NET 2003 Standard Edition, Microsoft Visual J# .NET 2003 Standard Edition

  • kbinfo kbsecurity KB306158
Comentarios
(m);