Les réponses ci-dessus avec IsInRole sont en fait correctes : cela vérifie si l'utilisateur actuel a le privilège administrateur. Cependant,
À partir de Windows Vista, le Contrôle de compte d'utilisateur (UAC) détermine les privilèges d'un utilisateur. Si vous êtes membre du groupe Administrateurs intégrés, vous disposez de deux jetons d'accès en cours d'exécution : un jeton d'accès utilisateur standard et un jeton d'accès administrateur. Par défaut, vous êtes dans le rôle d'utilisateur standard.
(de MSDN, par exemple https://msdn.microsoft.com/en-us/library/system.diagnostics.eventlogpermission(v=vs.110).aspx)
Ainsi, IsInRole considérera par défaut le privilège de l'utilisateur, et donc la méthode renverra false. Seulement vrai lorsque le logiciel est explicitement exécuté en tant qu'administrateur.
L'autre méthode vérifiant dans l'AD sur https://ayende.com/blog/158401/are-you-an-administrator vérifiera si le nom d'utilisateur est dans un groupe d'administration.
Ma méthode complète combinant les deux est donc :
public static bool IsCurrentUserAdmin(bool checkCurrentRole = true)
{
bool isElevated = false;
using (WindowsIdentity identity = WindowsIdentity.GetCurrent())
{
if (checkCurrentRole)
{
// Même si l'utilisateur est défini dans le groupe Admin, UAC définit 2 rôles : un utilisateur et un administrateur.
// IsInRole considère le rôle par défaut actuel comme utilisateur, donc retournera false !
// Considérera le rôle administrateur uniquement si l'application est explicitement exécutée en tant qu'administrateur !
WindowsPrincipal principal = new WindowsPrincipal(identity);
isElevated = principal.IsInRole(WindowsBuiltInRole.Administrator);
}
else
{
// lire tous les rôles pour le nom d'identité actuel, en interrogeant ActiveDirectory
isElevated = IsAdministratorNoCache(identity.Name);
}
}
return isElevated;
}
///
/// Détermine si l'utilisateur spécifié est un administrateur.
///
/// Le nom d'utilisateur.
///
/// true si l'utilisateur spécifié est un administrateur ; sinon, false.
///
///
private static bool IsAdministratorNoCache(string username)
{
PrincipalContext ctx;
try
{
Domain.GetComputerDomain();
try
{
ctx = new PrincipalContext(ContextType.Domain);
}
catch (PrincipalServerDownException)
{
// impossible d'accéder au domaine, vérifier la machine locale à la place
ctx = new PrincipalContext(ContextType.Machine);
}
}
catch (ActiveDirectoryObjectNotFoundException)
{
// pas dans un domaine
ctx = new PrincipalContext(ContextType.Machine);
}
var up = UserPrincipal.FindByIdentity(ctx, username);
if (up != null)
{
PrincipalSearchResult authGroups = up.GetAuthorizationGroups();
return authGroups.Any(principal =>
principal.Sid.IsWellKnown(WellKnownSidType.BuiltinAdministratorsSid) ||
principal.Sid.IsWellKnown(WellKnownSidType.AccountDomainAdminsSid) ||
principal.Sid.IsWellKnown(WellKnownSidType.AccountAdministratorSid) ||
principal.Sid.IsWellKnown(WellKnownSidType.AccountEnterpriseAdminsSid));
}
return false;
}
Pour un utilisateur dans un groupe d'administration sans privilège élevé (UAC activé), cette méthode IsCurrentUserAdmin() renvoie !checkCurrentRole : true si checkCurrentRole==false, mais false si checkCurrentRole==true
Si vous exécutez du code qui REQUIERT un privilège administratif, envisagez de définir checkCurrentRole==true. Sinon, vous obtiendrez une exception de sécurité à ce moment-là. Par conséquent, la logique correcte de IsInRole.