Die Identität eines Windows-Benutzers
Ich bin mit dem code, um die Identität eines Benutzerkontos für den Zugriff auf eine Datei teilen.
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
}
Dann mit:
using (new Impersonator("username", "domain", "password"))
{
Process.Start("explorer.exe", @"/root,\\server01-Prod\abc");
}
Bekomme ich eine "Zugriff Verweigert" - Fehler.
Dieser Benutzer vermutlich Zugriff auf diese Freigabe. Kann ich ein Laufwerk zuzuordnen, verwenden Sie "net use" aber dieser code wird nicht funktionieren. Nun ich denke es ist der code. Hat jemand etwas sehen? Gibt es einen besseren Weg, dies zu tun?
- Wo ist diese Ausführung aus? Wenn dies ist eine app, die auf IIS gehostet wird, dann wird der Standard-IIS-Benutzer haben nicht die Rechte zu imitieren
- Ja. gehostete web-Anwendung in IIS
- Ich erinnere mich, ich hatte ein ähnliches problem, versuchen Sie, diesen code in eine einfache Konsolenanwendung, die mit Ihrem admin-Benutzer an. Ich bin nicht wirklich sicher, Sie werden in der Lage sein, dies zu tun aus einer web-Anwendung auf dem IIS ausgeführt wird. Dies ist etwas zu tun mit den Berechtigungen des ASP.NET Benutzer (soweit ich mich erinnere)
Du musst angemeldet sein, um einen Kommentar abzugeben.
versuchen Sie dies :
Verwendung :
Wenn ich verstehen richtig, die Absicht ist, führen Sie den Prozess in der identitätswechselkontext.
Den doc von CreateProcess (die verwendet wird, durch den Prozess.Start) sagt:
Wenn der aufrufende Prozess wird die Identität anderer Benutzer, der neue Prozess verwendet das token für den aufrufenden Prozess, nicht der Identitätswechsel-token. Ausgeführt wird der neue Prozess im Sicherheitskontext des Benutzers, vertreten durch den Identitätswechsel-token, verwenden Sie die CreateProcessAsUser-oder CreateProcessWithLogonW-Funktion.
So, bist du mit dem falschen API zu tun.
Statt mit Ihrem
Impersonator
Klasse, was passiert, wenn Sie anrufenProcess.Start
und pass in eineProcessStartInfo -
Instanz, enthält den Benutzernamen, das Passwort und die Domäne, die Sie möchten, führen Sie den Prozess wie?Vielleicht, wenn das funktioniert, dann ist dein
Impersonator
Klasse sollte eineProcessStartInfo
- Instanz und verwenden die, neue Prozesse zu erstellen (zu Kapseln, die innerhalb der Klasse selbst).Darüber hinaus pro die MSDN docs...
Muss man auch das Arbeitsverzeichnis beim Start eines Prozesses mit unterschiedlichen Benutzer-creds.
UseShellExecute = true
?ErrorDialog = true
dachte ich, Sie mussteUseShellExecute = true
. Und auchWorkingDirectory
auf dieProcessStartInfo
Instanz.