Implementazione della rappresentazione in un'applicazione ASP.NET

Questo articolo è stato precedentemente pubblicato con il codice di riferimento I306158
Questo articolo si riferisce ai seguenti spazi dei nomi delle librerie di classi di Microsoft .NET Framework:
  • System.Web.Security
  • System.Security.Principal
  • System.Runtime.InteropServices
Sommario
In questo articolo vengono descritti vari metodi per implementare la rappresentazione in un'applicazione ASP.NET.
Informazioni
Per rappresentare un utente su un thread in ASP.NET, è possibile utilizzare uno dei seguenti metodi, a seconda dei propri requisiti:
Nota È possibile utilizzare il codice riportato di seguito per determinare l'utente che viene rappresentato dal thread in esecuzione:
System.Security.Principal.WindowsIdentity.GetCurrent().Name				

Rappresentare l'account o l'utente autenticato IIS

Per rappresentare l'utente che richiede l'autenticazione IIS (Internet Information Services) per tutte le richieste in tutte le pagine di un'applicazione ASP.NET è necessario includere un tag <identity> nel file Web.config di tale applicazione e impostare l'attributo impersonate su true. Ad esempio:
<identity impersonate="true" />				
Torna all'inizio

Rappresentare un utente specifico per tutte le richieste di un'applicazione ASP.NET

Per rappresentare un utente specifico per tutte le richieste in tutte le pagine di un'applicazione ASP.NET è possibile specificare gli attributi userName e password nel tag <identity> del file Web.config per tale applicazione. Ad esempio:
<identity impersonate="true" userName="accountname" password="password" />				
Nota L'identità del processo che rappresenta uno specifico utente su un thread deve disporre del privilegio "Agisci come parte del sistema operativo". Per impostazione predefinita, il processo Aspnet_wp.exe viene eseguito a fronte di un account computer ASPNET. Questo account non dispone tuttavia dei privilegi richiesti per rappresentare un utente specifico. Per questa ragione, se si tenta di rappresentare un utente specifico verrà visualizzato un messaggio di errore. Queste informazioni si riferiscono solo a .NET Framework 1.0. Questo privilegio non è necessario per .NET Framework 1.1.

Per risolvere questo problema, utilizzare uno dei metodi descritti di seguito.
  • Concedere all'account ASPNET (quello che dispone di meno privilegi) il privilegio "Agisci come parte del sistema operativo".

    Nota Benché sia possibile utilizzare questo metodo per aggirare il problema, Microsoft ne sconsiglia l'uso.
  • Nella sezione di configurazione <processModel> del file Machine.config cambiare nell'account di sistema l'account a fronte del quale viene eseguito il processo Aspnet_wp.exe.
Torna all'inizio

Rappresentare l'utente che richiede l'autenticazione nel codice

Per rappresentare l'utente che richiede l'autenticazione (User.Identity) solo quando si esegue una particolare sezione di codice, utilizzare il codice riportato di seguito. Questo metodo prevede che l'identità dell'utente che richiede l'autenticazione sia di 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()'Insert your code that runs under the security context of the authenticating user here.impersonationContext.Undo()				
Visual C# .NET
System.Security.Principal.WindowsImpersonationContext impersonationContext;impersonationContext =     ((System.Security.Principal.WindowsIdentity)User.Identity).Impersonate();//Insert your code that runs under the security context of the authenticating user here.impersonationContext.Undo();				
Visual J# .NET
System.Security.Principal.WindowsImpersonationContext impersonationContext;impersonationContext =     ((System.Security.Principal.WindowsIdentity)get_User().get_Identity()).Impersonate();//Insert your code that runs under the security context of the authenticating user here.impersonationContext.Undo();				
Torna all'inizio

Rappresentare uno specifico utente nel codice

Per rappresentare uno specifico utente solo quando si esegue una particolare sezione di codice, utilizzare il codice riportato di seguito:

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        'Insert your code that runs under the security context of a specific user here.        undoImpersonation()    Else        'Your impersonation failed. Therefore, include a fail-safe mechanism here.    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"))	{		//Insert your code that runs under the security context of a specific user here.		undoImpersonation();	}	else	{		//Your impersonation failed. Therefore, include a fail-safe mechanism here.	}}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"))	{		//Insert your code that runs under the security context of a specific user here.		undoImpersonation();	}	else	{		//Your impersonation failed. Therefore, include a fail-safe mechanism here.	}}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 L'identità del processo che rappresenta uno specifico utente su un thread deve disporre del privilegio "Agisci come parte del sistema operativo". Per impostazione predefinita, il processo Aspnet_wp.exe viene eseguito a fronte di un account computer ASPNET. Questo account non dispone tuttavia dei privilegi richiesti per rappresentare un utente specifico. Per questa ragione, se si tenta di rappresentare un utente specifico verrà visualizzato un messaggio di errore. Queste informazioni si riferiscono solo a .NET Framework 1.0. Questo privilegio non è necessario per .NET Framework 1.1.

Per risolvere questo problema, utilizzare uno dei metodi descritti di seguito.
  • Concedere all'account ASPNET il privilegio "Agisci come parte del sistema operativo".

    Nota Per risolvere il problema, sconsigliamo di utilizzare questo metodo.
  • Nella sezione di configurazione <processModel> del file Machine.config cambiare nell'account di sistema l'account a fronte del quale viene eseguito il processo Aspnet_wp.exe.
Torna all'inizio
Riferimenti
Per ulteriori informazioni sul modello di protezione di ASP.NET, fare clic sul numero dell'articolo della Knowledge Base riportato di seguito:
306590 INFO: Cenni preliminari sulla protezione ASP.NET
login failed null (null) impersonate
Proprietà

ID articolo: 306158 - Ultima revisione: 08/16/2005 17:26:38 - Revisione: 4.8

Microsoft ASP.NET 1.1, Microsoft ASP.NET 1.0, 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
Feedback