Dynamiquement Usurper l'identité d'un utilisateur distant - c# et asp.net
Je veux usurper l'identité d'un utilisateur distant de manière dynamique pendant l'exécution d'une partie de code. Je searchd beaucoup net et ai quelques codes pour usurper l'identité. Le code d'usurper l'identité est indiqué ci-dessous
namespace Tools
{
#region Using directives.
//----------------------------------------------------------------------
using System;
using System.Security.Principal;
using System.Runtime.InteropServices;
using System.ComponentModel;
//----------------------------------------------------------------------
#endregion
/////////////////////////////////////////////////////////////////////////
///<summary>
///Impersonation of a user. Allows to execute code under another
///user context.
///Please note that the account that instantiates the Impersonator class
///needs to have the 'Act as part of operating system' privilege set.
///</summary>
///<remarks>
///This class is based on the information in the Microsoft knowledge base
///article http://support.microsoft.com/default.aspx?scid=kb;en-us;Q306158
///
///Encapsulate an instance into a using-directive like e.g.:
///
/// ...
/// using ( new Impersonator( "myUsername", "myDomainname", "myPassword" ) )
/// {
/// ...
/// [code that executes under the new context]
/// ...
/// }
/// ...
///
///Please contact the author Uwe Keim (mailto:[email protected])
///for questions regarding this class.
///</remarks>
public class Impersonator :
IDisposable
{
#region Public methods.
//------------------------------------------------------------------
///<summary>
///Constructor. Starts the impersonation with the given credentials.
///Please note that the account that instantiates the Impersonator class
///needs to have the 'Act as part of operating system' privilege set.
///</summary>
///<param name="userName">The name of the user to act as.</param>
///<param name="domainName">The domain name of the user to act as.</param>
///<param name="password">The password of the user to act as.</param>
public Impersonator(
string userName,
string domainName,
string password )
{
ImpersonateValidUser( userName, domainName, password );
}
//------------------------------------------------------------------
#endregion
#region IDisposable member.
//------------------------------------------------------------------
public void Dispose()
{
UndoImpersonation();
}
//------------------------------------------------------------------
#endregion
#region P/Invoke.
//------------------------------------------------------------------
[DllImport("advapi32.dll", SetLastError=true)]
private static extern int LogonUser(
string lpszUserName,
string lpszDomain,
string lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
private static extern int DuplicateToken(
IntPtr hToken,
int impersonationLevel,
ref IntPtr hNewToken);
[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
private static extern bool RevertToSelf();
[DllImport("kernel32.dll", CharSet=CharSet.Auto)]
private static extern bool CloseHandle(
IntPtr handle);
private const int LOGON32_LOGON_INTERACTIVE = 2;
private const int LOGON32_PROVIDER_DEFAULT = 0;
//------------------------------------------------------------------
#endregion
#region Private member.
//------------------------------------------------------------------
///<summary>
///Does the actual impersonation.
///</summary>
///<param name="userName">The name of the user to act as.</param>
///<param name="domainName">The domain name of the user to act as.</param>
///<param name="password">The password of the user to act as.</param>
private void ImpersonateValidUser(
string userName,
string domain,
string password )
{
WindowsIdentity tempWindowsIdentity = null;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;
try
{
if ( RevertToSelf() )
{
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();
}
else
{
throw new Win32Exception( Marshal.GetLastWin32Error() );
}
}
else
{
throw new Win32Exception( Marshal.GetLastWin32Error() );
}
}
else
{
throw new Win32Exception( Marshal.GetLastWin32Error() );
}
}
finally
{
if ( token!= IntPtr.Zero )
{
CloseHandle( token );
}
if ( tokenDuplicate!=IntPtr.Zero )
{
CloseHandle( tokenDuplicate );
}
}
}
///<summary>
///Reverts the impersonation.
///</summary>
private void UndoImpersonation()
{
if ( impersonationContext!=null )
{
impersonationContext.Undo();
}
}
private WindowsImpersonationContext impersonationContext = null;
//------------------------------------------------------------------
#endregion
}
/////////////////////////////////////////////////////////////////////////
}
et le code qui appelle les fonctions ci-dessus est illustré ci-dessous
using System;
using System.IO;
using Tools;
namespace ImpersonatorDemo
{
///<summary>
///Main class for the demo application.
///Call this application with a low privileg account to test.
///</summary>
class Program
{
///<summary>
///The main entry point.
///</summary>
[STAThread]
static void Main( string[] args )
{
//Impersonate, automatically release the impersonation. format is new Impersonator( "username", "domain", "password" )
using ( new Impersonator( "TestUser", "MachineA", "admin" ) )
{
string name = Environment.UserDomainName;
string s = Environment.UserName;
//The following code is executed under the impersonated user.
string[] files = Directory.GetFiles( "c:\\" );
}
}
}
}
Il fonctionne très bien si j'essaie d'usurper l'identité de l'utilisateur sur la machine locale. Mais si j'ai essayé de imporsenate un utilisateur sur la machine distante, il jette toujours une erreur .ce qui est indiqué ci-dessous
Logon failure: unknown user name or bad password
sur la machine distante, il est un utilisateur nommé Testuser et le mot de passe est admin et le nom de la machine est MachineA ( thi est le nom de domaine??) et l'adresse ip est 192.168.0.33 . le groupe de travail est myWorkGroup .J'ai essayé d'usurper l'identité des utilisateurs sur de nombreux mremote de la machine . Mais il indique toujours le même message d'erreur que j'ai écrit ci-dessus, si je suis tryied à usurper l'identité d'un utilisateur distant. et je suis sûr que ma machine locale est connecté au réseau
OriginalL'auteur Null Pointer | 2010-11-18
Vous devez vous connecter pour publier un commentaire.
Comme je comprends votre problème, le ImpersonateDemo code ci-dessus fonctionne sur votre serveur (ServerA).
ServerA essaie d'obtenir une liste de fichiers sur une machine distante (MachineA).
Si votre code sur le ServerA demandes les fichiers dans le répertoire C:\, vous allez toujours obtenir les fichiers sur votre serveur C lecteur.
C'est pourquoi, lorsque vous emprunter l'identité d'un utilisateur local (sur le ServerA), il fonctionne - parce que l'utilisateur est sur la machine que l'unité est en marche. Lorsque vous emprunter l'identité avec l'utilisateur distant (à partir de MachineA) vous êtes encore en train d'essayer d'obtenir le contenu de ServerA du disque C, mais que l'utilisateur n'existe pas sur le ServerA.
Vous avez besoin de demander des fichiers sur la base de l'adresse IP (ou nom de la machine) de la machine distante. Si le TestUser a l'autorisation de lire MachineA du lecteur C, puis essayez ceci:
OriginalL'auteur PhillFox
Cela ressemble, c'est une manifestation de la double saut problème:
http://blogs.msdn.com/b/knowledgecast/archive/2007/01/31/the-double-hop-problem.aspx
OriginalL'auteur Rich
Usurper l'identité n'est pas aussi simple que ça ressemble. Alors que le code à usurper l'identité est assez simple, trouver les arguments peut-être pas. Il dépend de la façon dont vous devez vous authentifier votre utilisateur -> un groupe de travail diffère d'un domaine diffère d'une machine, etc...
Pour votre groupe de travail, c'est important si l'utilisateur est connu sur les deux machines ou pas. Comme une simple approche technique, vous devriez essayer de quitter le domaine/nom de la machine vide.
Vérifiez également Ricks post, le double saut stuff est assez gênant quand woring avec usurpation d'identité 🙁
OriginalL'auteur Jaster