Cet article explique les différentes méthodes d'implémentation d'un emprunt d'identité dans une application ASP.NET.
Pour emprunter l'identité d'un utilisateur dans une thread dans ASP.NET, vous pouvez utiliser l'une des méthodes suivantes, en fonction de vos besoins :
REMARQUE : pour déterminer sous quel utilisateur la thread s'exécute, vous pouvez utiliser le code suivant :
System.Security.Principal.WindowsIdentity.GetCurrent().Name
Emprunt de l'identité d'un compte ou d'un utilisateur authentifié IIS
Pour emprunter l'identité d'un utilisateur d'authentification Microsoft Internet Information Services (IIS) pour chaque demande de page dans une application ASP.NET, vous devez insérer la balise
<identity> dans le fichier Web.config de cette application et attribuer à l'attribut
impersonate la valeur
true. Par exemple :
<identity impersonate="true" />
Emprunt de l'identité d'un utilisateur particulier pour toutes les demandes d'une application ASP.NET
Pour emprunter l'identité d'un utilisateur particulier pour toutes les demandes de page d'une application ASP.NET, vous pouvez spécifier les attributs
userName et
password de la balise
<identity> du fichier Web.config de cette application. Par exemple :
<identity impersonate="true" userName="nomducompte" password="motdepasse" />
REMARQUE : l'identité du processus d'emprunt d'un utilisateur particulier dans une thread doit posséder le privilège d'agir en tant que partie du système d'exploitation. Par défaut, le processus Aspnet_wp.exe s'exécute sous un compte de l'ordinateur appelé ASPNET. Ce compte ne possède cependant pas les privilèges nécessaires pour emprunter l'identité d'un utilisateur particulier. Si vous tentez d'emprunter l'identité d'un utilisateur particulier, un message d'erreur s'affiche.
Pour contourner ce problème, utilisez l'une des méthodes suivantes :
- Accordez le privilège Agir en tant que partie du système d'exploitation au compte ASPNET.
- Remplacez le compte sous lequel le processus Aspnet_wp.exe s'exécute par le compte système dans la section de configuration <processModel> du fichier Machine.config.
Emprunt de l'identité de l'utilisateur d'authentification dans le code
Pour n'emprunter l'identité de l'utilisateur d'authentification (
User.Identity ) que lorsque vous exécutez une section particulière du code, vous pouvez utiliser le code ci-dessous. Pour cette méthode, l'identité de l'utilisateur d'authentification doit être du type
WindowsIdentity.
Visual Basic .NET
Dim impersonationContext As System.Security.Principal.WindowsImpersonationContext
Dim currentWindowsIdentity As System.Security.Principal.WindowsIdentity
currentWindowsIdentity = CType(User.Identity, System.Security.Principal.WindowsIdentity)
impersonationContext = currentWindowsIdentity.Impersonate()
'Insérez ici le code qui s'exécute dans le contexte de sécurité de l'utilisateur d'authentification.
impersonationContext.Undo()
Visual C# .NET
System.Security.Principal.WindowsImpersonationContext impersonationContext;
impersonationContext = ((System.Security.Principal.WindowsIdentity)User.Identity).Impersonate();
// Insérez ici le code qui s'exécute dans le contexte de sécurité de l'utilisateur d'authentification.
impersonationContext.Undo();
Emprunt de l'identité d'un utilisateur particulier dans le code
Pour n'emprunter l'identité d'un utilisateur particulier que lorsque vous exécutez une section particulière du code, utilisez le code ci-dessous :
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 = 2
Dim LOGON32_PROVIDER_DEFAULT As Integer = 0
Dim impersonationContext As WindowsImpersonationContext
Declare Auto Function LogonUser 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, _
ImpersonationLevel As Integer, _
ByRef DuplicateTokenHandle As IntPtr) As Integer
Public Sub Page_Load(s As Object, e As EventArgs)
If impersonateValidUser("nomutilisateur", "domaine", "motdepasse") Then
'Insérez ici le code qui s'exécute dans le contexte de sécurité de l'utilisateur particulier.
undoImpersonation()
Else
'L'emprunt d'identité a échoué. Par conséquent, insérez ici un mécanisme de prévention de défaillance.
End If
End Sub
Private Function impersonateValidUser(userName As String, _
domain As String, password As String) As Boolean
Dim tempWindowsIdentity As WindowsIdentity
Dim token As IntPtr
Dim tokenDuplicate As IntPtr
If LogonUser(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 impersonationContext Is Nothing Then
impersonateValidUser = False
Else
impersonateValidUser = True
End If
Else
impersonateValidUser = False
End If
Else
impersonateValidUser = False
End If
End Function
Private 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", CharSet=CharSet.Auto)]
public static extern int LogonUser(String lpszUserName,
String lpszDomain,
String lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
[DllImport("advapi32.dll", CharSet=System.Runtime.InteropServices.CharSet.Auto, SetLastError=true)]
public extern static int DuplicateToken(IntPtr hToken,
int impersonationLevel,
ref IntPtr hNewToken);
public void Page_Load(Object s, EventArgs e)
{
if(impersonateValidUser("nomutilisateur", "domaine", "motdepasse"))
{
// Insérez ici le code qui s'exécute dans le contexte de sécurité de l'utilisateur particulier.
undoImpersonation();
}
else
{
// L'emprunt d'identité a échoué. Par conséquent, insérez ici un mécanisme de prévention de défaillance.
}
}
private bool impersonateValidUser(String userName, String domain, String password)
{
WindowsIdentity tempWindowsIdentity;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;
if(LogonUser(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)
return true;
else
return false;
}
else
return false;
}
else
return false;
}
private void undoImpersonation()
{
impersonationContext.Undo();
}
</script> REMARQUE : l'identité du processus d'emprunt d'un utilisateur particulier dans une thread doit posséder le privilège Agir en tant que partie du système d'exploitation. Par défaut, le processus Aspnet_wp.exe s'exécute sous un compte de l'ordinateur appelé ASPNET. Ce compte ne possède cependant pas les privilèges nécessaires pour emprunter l'identité d'un utilisateur particulier. Si vous tentez d'emprunter l'identité d'un utilisateur particulier, un message d'erreur s'affiche.
Pour contourner ce problème, utilisez l'une des méthodes suivantes :
- Accordez le privilège Agir en tant que partie du système d'exploitation au compte ASPNET.
- Remplacez le compte sous lequel le processus Aspnet_wp.exe s'exécute par le compte système dans la section de configuration <processModel> du fichier Machine.config.
Pour plus d'informations sur la sécurité ASP.NET, cliquez sur le numéro ci-dessous pour afficher l'article correspondant dans la Base de connaissances Microsoft :
306590
(http://support.microsoft.com/kb/306590/FR/
)
INFO : Présentation générale de la sécurité ASP.NET