Mi aplicación necesita ejecutar algunos scripts y debo estar seguro de que el usuario que los ejecuta sea un administrador ... ¿Cuál es la mejor manera de hacer esto usando C #?
c#
windows-administration
Fliskov
fuente
fuente
return new WindowsPrincipal(WindowsIdentity.GetCurrent()) .IsInRole(WindowsBuiltInRole.Administrator);
fuente
También puede llamar a la API de Windows para hacer esto:
[DllImport("shell32.dll", SetLastError=true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool IsUserAnAdmin();
que le dice de manera más genérica si el usuario se está ejecutando con derechos elevados.
fuente
Las respuestas anteriores con IsInRole son realmente correctas: comprueba si el usuario actual tiene privilegios de administrador. Sin embargo,
(de MSDN, por ejemplo, https://msdn.microsoft.com/en-us/library/system.diagnostics.eventlogpermission(v=vs.110).aspx )
Por lo tanto, IsInRole considerará por defecto el privilegio del usuario y, por lo tanto, el método devolverá falso. Solo es cierto cuando el software se ejecuta explícitamente como administrador.
El otro método de verificación de AD en https://ayende.com/blog/158401/are-you-an-administrator verificará si el nombre de usuario está en un grupo de administradores.
Mi método completo combinando ambos es así:
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; }
Para un usuario en un grupo de administración sin privilegios elevados (UAC habilitado), este método IsCurrentUserAdmin () return! CheckCurrentRole: true si checkCurrentRole == false, pero falso si checkCurrentRole == true
Si ejecuta código que REQUIERE privilegios de administrador, considere checkCurrentRole == true. De lo contrario, obtendrá una excepción de seguridad para entonces. Por lo tanto, la lógica IsInRole correcta .
fuente
Solo pensé en agregar otra solución; ya
IsInRole
que no siempre funciona.Dependiendo de sus necesidades si necesita admitir sistemas más antiguos; o no está seguro de cómo su cliente está administrando físicamente su sistema. Esta es una solución que implementé; para flexibilidad y alteraciones.
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.
Entonces, el código anterior tiene algunas construcciones; en realidad, probará para ver si el usuario está en Vista o superior. De esa manera, si un cliente está en XP sin un marco o marco beta de hace años, le permitirá modificar lo que le gustaría hacer.
Luego, probará físicamente para evitar un valor nulo para la cuenta.
Luego, por último, proporcionará la verificación para verificar que el usuario esté realmente en el rol adecuado.
Sé que la pregunta ha sido respondida; pero pensé que mi solución sería una gran adición a la página para cualquier otra persona que esté buscando en Stack. Mi razonamiento detrás del Constructor protegido le permitiría usar esta clase como una Clase derivada en la que podría controlar el estado en el que se crea una instancia de la clase.
fuente
Si su aplicación debe ejecutarse con derechos de administrador, sería correcto actualizar su manifiesto.
Establecer
requestedExecutionlevel
enrequireAdminstrator
.fuente
Así es como termino ... estoy forzando a que mi aplicación se ejecute como modo administrador. Para hacer esto
1- Agregue
<ApplicationManifest>app.manifest</ApplicationManifest>
a sucsproj
archivo.MyProject.csproj
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>netcoreapp3.1</TargetFramework> <ApplicationManifest>app.manifest</ApplicationManifest> </PropertyGroup> </Project>
2- Agrega el siguiente
app.manifest
archivo a tu proyecto.app.manifest
<?xml version="1.0" encoding="utf-8"?> <assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1"> <assemblyIdentity version="1.0.0.0" name="MyApplication.app"/> <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"> <security> <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3"> <requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> </requestedPrivileges> </security> </trustInfo> </assembly>
fuente