Comment utiliser LogonUser correctement pour imiter l'utilisateur du domaine du client workgroup
ASP.NET: Impersonate contre un domaine sur VMWare
cette question Est ce que je demande, mais la réponse ne fournit pas de détails sur la façon dont le _token est dérivé. Il semble n'utiliser que WindowsIdentity.GetCurrent().Token
donc il n'y a pas d'usurpation d'identité.
puis-je imiter un utilisateur sur un autre domaine Active Directory dans .NET?
Cette question a des réponses contradictoires, avec celui accepté portant un commentaire "je commence à soupçonner que mon problème réside ailleurs."Pas utile.
LogonUser ne fonctionne que pour mon domaine
cette question suivante semble impliquer que ce n'est pas possible, mais elle traite de 2 domaines, donc je ne suis pas sûr si elle est pertinente.
ma vraie question Est:
- est-ce possible? et si oui,
- comment? ou Où ai-je mal tourné?
ce que j'ai essayé jusqu'à présent est, en utilisant le code de http://msdn.microsoft.com/en-us/library/chf6fbt4%28v=VS.80%29.aspx
bool returnValue = LogonUser(user, domain, password,
LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT,
ref tokenHandle);
// after this point, returnValue = false
L'erreur Win32 est
échec de connexion: nom d'utilisateur inconnu ou mauvais mot de passe
6 réponses
très peu de billets suggèrent d'utiliser LOGON_TYPE_NEW_CREDENTIALS
au lieu de LOGON_TYPE_NETWORK
ou LOGON_TYPE_INTERACTIVE
. J'ai eu un problème d'usurpation d'identité avec une machine connectée à un domaine et une autre non, et cela l'a corrigé.
Le dernier extrait de code dans ce post suggère que l'usurpation d'identité à travers une forêt fonctionne, mais il ne dit pas spécifiquement quoi que ce soit sur la confiance étant mis en place. Cela vaut donc peut-être la peine d'essayer:
const int LOGON_TYPE_NEW_CREDENTIALS = 9;
const int LOGON32_PROVIDER_WINNT50 = 3;
bool returnValue = LogonUser(user, domain, password,
LOGON_TYPE_NEW_CREDENTIALS, LOGON32_PROVIDER_WINNT50,
ref tokenHandle);
MSDN dit que LOGON_TYPE_NEW_CREDENTIALS
ne fonctionne qu'avec LOGON32_PROVIDER_WINNT50
.
cela fonctionne pour moi, exemple de travail complet (je souhaite que plus de gens feraient cela):
//logon impersonation
using System.Runtime.InteropServices; // DllImport
using System.Security.Principal; // WindowsImpersonationContext
using System.Security.Permissions; // PermissionSetAttribute
...
class Program {
// obtains user token
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool LogonUser(string pszUsername, string pszDomain, string pszPassword,
int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
// closes open handes returned by LogonUser
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public extern static bool CloseHandle(IntPtr handle);
public void DoWorkUnderImpersonation() {
//elevate privileges before doing file copy to handle domain security
WindowsImpersonationContext impersonationContext = null;
IntPtr userHandle = IntPtr.Zero;
const int LOGON32_PROVIDER_DEFAULT = 0;
const int LOGON32_LOGON_INTERACTIVE = 2;
string domain = ConfigurationManager.AppSettings["ImpersonationDomain"];
string user = ConfigurationManager.AppSettings["ImpersonationUser"];
string password = ConfigurationManager.AppSettings["ImpersonationPassword"];
try {
Console.WriteLine("windows identify before impersonation: " + WindowsIdentity.GetCurrent().Name);
// if domain name was blank, assume local machine
if (domain == "")
domain = System.Environment.MachineName;
// Call LogonUser to get a token for the user
bool loggedOn = LogonUser(user,
domain,
password,
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT,
ref userHandle);
if (!loggedOn) {
Console.WriteLine("Exception impersonating user, error code: " + Marshal.GetLastWin32Error());
return;
}
// Begin impersonating the user
impersonationContext = WindowsIdentity.Impersonate(userHandle);
Console.WriteLine("Main() windows identify after impersonation: " + WindowsIdentity.GetCurrent().Name);
//run the program with elevated privileges (like file copying from a domain server)
DoWork();
} catch (Exception ex) {
Console.WriteLine("Exception impersonating user: " + ex.Message);
} finally {
// Clean up
if (impersonationContext != null) {
impersonationContext.Undo();
}
if (userHandle != IntPtr.Zero) {
CloseHandle(userHandle);
}
}
}
private void DoWork() {
//everything in here has elevated privileges
//example access files on a network share through e$
string[] files = System.IO.Directory.GetFiles(@"\domainserver\e$\images", "*.jpg");
}
}
j'ai réussi à imiter des utilisateurs dans un autre domaine, mais seulement avec une confiance établie entre les deux domaines.
var token = IntPtr.Zero;
var result = LogonUser(userID, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token);
if (result)
{
return WindowsIdentity.Impersonate(token);
}
j'avais le même problème. Je ne sais pas si vous avez résolu ceci ou non, mais ce que j'essayais vraiment de faire était d'accéder à un partage de réseau avec des identifiants publicitaires. WNetAddConnection2()
est ce que vous devez utiliser dans ce cas.
Connexion/Mot de passe invalide pourrait aussi être lié à des problèmes dans votre serveur DNS - c'est ce qui m'est arrivé et m'a coûté bon 5 heures de ma vie. Voir si vous pouvez spécifier l'adresse ip à la place sur le nom de domaine.
il est préférable d'utiliser une sécurisation:
var password = new SecureString();
var phPassword phPassword = Marshal.SecureStringToGlobalAllocUnicode(password);
IntPtr phUserToken;
LogonUser(username, domain, phPassword, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, out phUserToken);
et:
Marshal.ZeroFreeGlobalAllocUnicode(phPassword);
password.Dispose();
définition de la fonction:
private static extern bool LogonUser(
string pszUserName,
string pszDomain,
IntPtr pszPassword,
int dwLogonType,
int dwLogonProvider,
out IntPtr phToken);