Mon application doit exécuter des scripts et je dois m'assurer que l'utilisateur qui les exécute est un administrateur ... Quelle est la meilleure façon de procéder à l'aide de C #?
using System.Security.Principal;
public static bool IsAdministrator()
{
using (WindowsIdentity identity = WindowsIdentity.GetCurrent())
{
WindowsPrincipal principal = new WindowsPrincipal(identity);
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}
}
return new WindowsPrincipal(WindowsIdentity.GetCurrent())
.IsInRole(WindowsBuiltInRole.Administrator);
Vous pouvez également appeler l'API Windows pour effectuer cette opération:
[DllImport("Shell32.dll", SetLastError=true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool IsUserAnAdmin();
qui vous indique de manière plus générique si l’utilisateur fonctionne sous des droits élevés.
Les réponses ci-dessus avec IsInRole sont en réalité correctes: il vérifie si l'utilisateur actuel dispose des privilèges d'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, deux jetons d'accès au moment de l'exécution vous sont attribués: 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.
(à partir 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 la méthode retournera donc false. Vrai seulement lorsque le logiciel est explicitement exécuté en tant qu'administrateur.
L’autre méthode qui vérifie AD dans https://ayende.com/blog/158401/are-you-an-administrator vérifie si le nom de l’utilisateur appartient à un groupe d’administrateurs.
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)
{
// Even if the user is defined in the Admin group, UAC defines 2 roles: one user and one admin.
// IsInRole consider the current default role as user, thus will return false!
// Will consider the admin role only if the app is explicitly run as admin!
WindowsPrincipal principal = new WindowsPrincipal(identity);
isElevated = principal.IsInRole(WindowsBuiltInRole.Administrator);
}
else
{
// read all roles for the current identity name, asking ActiveDirectory
isElevated = IsAdministratorNoCache(identity.Name);
}
}
return isElevated;
}
/// <summary>
/// Determines whether the specified user is an administrator.
/// </summary>
/// <param name="username">The user name.</param>
/// <returns>
/// <c>true</c> if the specified user is an administrator; otherwise, <c>false</c>.
/// </returns>
/// <seealso href="https://ayende.com/blog/158401/are-you-an-administrator"/>
private static bool IsAdministratorNoCache(string username)
{
PrincipalContext ctx;
try
{
Domain.GetComputerDomain();
try
{
ctx = new PrincipalContext(ContextType.Domain);
}
catch (PrincipalServerDownException)
{
// can't access domain, check local machine instead
ctx = new PrincipalContext(ContextType.Machine);
}
}
catch (ActiveDirectoryObjectNotFoundException)
{
// not in a domain
ctx = new PrincipalContext(ContextType.Machine);
}
var up = UserPrincipal.FindByIdentity(ctx, username);
if (up != null)
{
PrincipalSearchResult<Principal> 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 d'un groupe d'administrateur 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 le privilège administrateur, considérez le paramètre checkCurrentRole == true. Sinon, vous obtiendrez une exception de sécurité d'ici là . Par conséquent, la logique IsInRole correcte.
Je pensais juste que j'ajouterais une autre solution; comme la IsInRole
ne fonctionne pas toujours.
En fonction de vos besoins, si vous devez prendre en charge des systèmes plus anciens. ou ne savez pas comment votre client gère physiquement votre système. C'est une solution que j'ai implémentée. pour la flexibilité et les modifications.
class Elevated_Rights
{
// Token Bool:
private bool _level = false;
#region Constructor:
protected Elevated_Rights()
{
// Invoke Method On Creation:
Elevate();
}
#endregion
public void Elevate()
{
// Get Identity:
WindowsIdentity user = WindowsIdentity.GetCurrent();
// Set Principal
WindowsPrincipal role = new WindowsPrincipal(user);
#region Test Operating System for UAC:
if (Environment.OSVersion.Platform != PlatformID.Win32NT || Environment.OSVersion.Version.Major < 6)
{
// False:
_level = false;
// Todo: Exception/ Exception Log
}
#endregion
else
{
#region Test Identity Not Null:
if (user == null)
{
// False:
_level = false;
// Todo: "Exception Log / Exception"
}
#endregion
else
{
#region Ensure Security Role:
if (!(role.IsInRole(WindowsBuiltInRole.Administrator)))
{
// False:
_level = false;
// Todo: "Exception Log / Exception"
}
else
{
// True:
_level = true;
}
#endregion
} // Nested Else 'Close'
} // Initial Else 'Close'
} // End of Class.
Donc, le code ci-dessus a quelques constructions; il va effectivement tester pour voir si l'utilisateur est sur Vista ou supérieur. Ainsi, si un client est sur XP sans un cadre ou un cadre bêta d’il ya des années, cela vous permettra de modifier ce que vous souhaitez faire.
Ensuite, il va tester physiquement pour éviter une valeur nulle pour le compte.
Enfin, il fournira le moyen de vérifier que l'utilisateur joue bien le rôle qui convient.
Je sais que la question a été répondue; mais je pensais que ma solution serait un excellent ajout à la page pour toute autre personne cherchant Stack. Mon raisonnement derrière le constructeur protégé vous permettrait d'utiliser cette classe en tant que classe dérivée que vous pouvez contrôler l'état de l'instanciation de la classe.
Je dois être sûr que l'utilisateur qui les exécute est un administrateur
Si votre application doit être exécutée avec des droits d'administrateur, il serait correct de mettre à jour son manifeste.
Définissez requestedExecutionlevel
sur requireAdminstrator
.