Usurper l'identité d'un utilisateur de Windows
Je suis en utilisant le code d'usurper l'identité d'un compte d'utilisateur pour accéder à un partage de fichiers.
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
}
Ensuite à l'aide d':
using (new Impersonator("username", "domain", "password"))
{
Process.Start("explorer.exe", @"/root,\\server01-Prod\abc");
}
J'obtiens une erreur "Accès Refusé".
Cet utilisateur supposely a accès à ce partage. Je peux mapper un lecteur, utilisez la commande "net use" mais ce code ne fonctionnera pas. Maintenant, je pense c'est le code. Personne ne voit rien? Est-il une meilleure manière de faire ceci?
Où est-ce en cours d'exécution? Si c'est une application hébergée sur IIS, puis l'IIS par défaut, l'utilisateur peut ne pas avoir les droits pour usurper l'identité d'
Oui. hébergé application web dans IIS
Je me souviens que j'avais un problème similaire, essayez d'exécuter ce code dans une application console à l'aide de votre compte d'utilisateur admin. Je ne suis pas réellement sûr que vous serez en mesure de le faire à partir d'une application web s'exécutant sur IIS. C'est quelque chose à voir avec les autorisations de l'ASP.NET utilisateur (comme je me souviens bien)
Oui. hébergé application web dans IIS
Je me souviens que j'avais un problème similaire, essayez d'exécuter ce code dans une application console à l'aide de votre compte d'utilisateur admin. Je ne suis pas réellement sûr que vous serez en mesure de le faire à partir d'une application web s'exécutant sur IIS. C'est quelque chose à voir avec les autorisations de l'ASP.NET utilisateur (comme je me souviens bien)
OriginalL'auteur Kyle Johnson | 2012-03-28
Vous devez vous connecter pour publier un commentaire.
essayez ceci :
Utilisation :
OriginalL'auteur Royi Namir
Si je comprends correctement, votre intention est de lancer le processus dans le contexte d'emprunt d'identité.
La doc de la fonction CreateProcess (qui est utilisé par le Processus.Démarrer) dit:
Si le processus appelant est usurper l'identité d'un autre utilisateur, le nouveau processus utilise le jeton pour le processus appelant, et non pas le jeton d'emprunt d'identité. Pour exécuter le nouveau processus dans le contexte de sécurité de l'utilisateur représenté par le jeton d'emprunt d'identité, l'utilisation de la CreateProcessAsUser ou CreateProcessWithLogonW fonction.
Donc, vous utilisez la mauvaise API pour le faire.
OriginalL'auteur Peter
Au lieu d'utiliser votre
Impersonator
classe, ce qui se passe lorsque vous appelezProcess.Start
et passez dans unProcessStartInfo
instance qui contient le nom d'utilisateur, mot de passe et le domaine que vous souhaitez exécuter le processus?Peut-être, si cela fonctionne, votre
Impersonator
classe devrait créer unProcessStartInfo
instance et l'utiliser pour créer de nouveaux processus (encapsuler qu'au sein de la classe elle-même).Aussi, par la MSDN docs...
Vous devez également définir le répertoire de travail lors du démarrage d'un processus avec les différents utilisateurs de l'creds.
Ce qui se passe lorsque vous définissez
UseShellExecute = true
?De Plus, si vous définissez
ErrorDialog = true
, je pensais que vous aviez à définirUseShellExecute = true
. Et aussi de mettre enWorkingDirectory
sur leProcessStartInfo
instance.Fait et j'ai eu une erreur. L'objet de Processus doit avoir la UseShellExecute propriété est définie sur false dans le but de démarrer un processus, comme un Code d'utilisateur - psi.Domain = "Domain"; psi.Nom d'utilisateur = "user"; psi.Mot de passe = pwd; psi.WorkingDirectory = @"C:\WINDOWS"; psi.FileName = "explorer.exe"; psi.Arguments = @"/root,\\serveur-01-PV\abc"; psi.ErrorDialog = true; psi.UseShellExecute = true; Processus.Start(psi);
psi.UseShellExecute = false, n'est-ce pas?
OriginalL'auteur David Hoerster