Проверьте, является ли текущий пользователь администратором
Мое приложение должно запускать некоторые сценарии, и я должен быть уверен, что пользователь, выполняющий их, является администратором... Каков наилучший способ сделать это с помощью C#?
9 ответов
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);
Вы также можете вызвать Windows API для этого:
[DllImport("shell32.dll", SetLastError=true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool IsUserAnAdmin();
который более обобщенно говорит вам, работает ли пользователь с повышенными правами.
Приведенные выше ответы с IsInRole действительно верны: он проверяет, есть ли у текущего пользователя права администратора. Тем не мение,
Начиная с Windows Vista, Контроль учетных записей (UAC) определяет привилегии пользователя. Если вы являетесь членом группы "Встроенные администраторы", вам назначаются два токена доступа во время выполнения: стандартный токен доступа пользователя и токен доступа администратора. По умолчанию вы находитесь в роли стандартного пользователя.
(из MSDN, например, https://msdn.microsoft.com/en-us/library/system.diagnostics.eventlogpermission(v=vs.110).aspx)
Таким образом, IsInRole по умолчанию учитывает пользовательские привилегии, и, таким образом, метод возвращает false. Истинно, только если программа явно запущена от имени администратора.
Другой метод проверки AD в https://ayende.com/blog/158401/are-you-an-administrator проверит, входит ли имя пользователя в группу администраторов.
Мой полный метод, объединяющий оба:
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;
}
Для пользователя в группе администраторов без повышенных привилегий (UAC включен) этот метод IsCurrentUserAdmin() возвращает! CheckCurrentRole: true, если checkCurrentRole==false, но false, если checkCurrentRole==true.
Если вы запускаете код, который ТРЕБУЕТ привилегий администратора, рассмотрите checkCurrentRole==true. В противном случае вы получите исключение безопасности к тому времени. Поэтому правильная логика IsInRole.
Как и другие здесь, моя программа не работает с повышенными привилегиями, поэтому этот код возвращает
false
включен ли UAC:
private bool IsCurrentUserAnAdmin()
{
var principal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}
Ответ @EricBDev с возвратом
true
если моя программа не работает с повышенными правами, а пользователь является администратором. Однако, как говорит автор блога, это очень медленно.
Вот мое решение; он подражает
IsAdministratorNoCache
но быстро:
private bool IsCurrentUserInAdminGroup()
{
// https://docs.microsoft.com/en-us/troubleshoot/windows-server/identity/security-identifiers-in-windows
// S-1-5-32-544
// A built-in group. After the initial installation of the operating system,
// the only member of the group is the Administrator account.
// When a computer joins a domain, the Domain Admins group is added to
// the Administrators group. When a server becomes a domain controller,
// the Enterprise Admins group also is added to the Administrators group.
var principal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
var claims = principal.Claims;
return (claims.FirstOrDefault(c => c.Value == "S-1-5-32-544") != null);
}
Ответ Дэвида Чинга хорош, но оставляет вам жестко закодированный идентификатор для группы администраторов. Это немного яснее:
private bool IsCurrentUserInAdminGroup()
{
var claims = new WindowsPrincipal(WindowsIdentity.GetCurrent()).Claims;
var adminClaimID = new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null).Value;
return claims.Any(c => c.Value == adminClaimID);
}
Просто подумал, что добавлю другое решение; как IsInRole
не всегда работает
- Если пользователь не является членом указанной группы пользователей Windows в текущем сеансе.
- Администратор внес изменения в параметры групповой политики.
- Параметр роли обрабатывается как метод с учетом регистра.
- И если на машине с XP не установлена версия.NET Framework, она не будет работать.
В зависимости от ваших потребностей, если вам нужно поддерживать старые системы; или не уверены, как ваш клиент физически управляет вашей системой. Это решение, которое я реализовал; для гибкости и переделок.
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.
Таким образом, приведенный выше код имеет несколько конструкций; это фактически проверит, чтобы видеть, является ли Пользователь на Vista или выше. Таким образом, если клиент работает на XP без фреймворка или бета-фреймворка много лет назад, это позволит вам изменить то, что вы хотели бы сделать.
Затем он будет физически проверен, чтобы избежать нулевого значения для учетной записи.
Затем, в конце концов, он предоставит проверку, чтобы убедиться, что пользователь действительно играет надлежащую роль.
Я знаю, что на вопрос был дан ответ; но я думал, что мое решение будет отличным дополнением к странице для всех, кто ищет в стеке. Мои рассуждения о Защищенном конструкторе позволили бы вам использовать этот класс в качестве производного класса, в котором вы можете контролировать состояние, когда создается экземпляр класса.
Я должен быть уверен, что пользователь, выполняющий их, является администратором
Если ваше приложение должно быть запущено с правами администратора, было бы правильно обновить его манифест.
Задавать requestedExecutionlevel
в requireAdminstrator
,
Вот как я закончил... Я заставляю свое приложение запускаться в режиме администратора. Сделать это
1- Добавить <ApplicationManifest>app.manifest</ApplicationManifest>
на ваш csproj
файл.
MyProject.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>
</Project>
2- Добавьте ниже app.manifest
файл в свой проект.
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>