检查当前用户是否是pipe理员
我的应用程序需要运行一些脚本,我必须确保运行它们的用户是一个pipe理员…使用C#这样做的最好方法是什么?
using System.Security.Principal; public static bool IsAdministrator() { WindowsIdentity identity = WindowsIdentity.GetCurrent(); WindowsPrincipal principal = new WindowsPrincipal(identity); return principal.IsInRole(WindowsBuiltInRole.Administrator); }
return new WindowsPrincipal(WindowsIdentity.GetCurrent()) .IsInRole(WindowsBuiltInRole.Administrator);
只是想我会添加另一个解决scheme; 因为IsInRole
并不总是工作。
- 如果用户不是当前会话中指定的Windows用户组的成员。
- pipe理员已对组策略设置进行了更改
- angular色参数被视为“区分大小写”的方法。
- 如果XP机器没有安装.NET Framework版本,它将无法工作。
根据您的需要,如果您需要支持旧系统; 或者不确定你的客户是如何实际pipe理你的系统的。 这是我实施的解决scheme; 灵活性和改变。
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.
所以上面的代码有一些构造; 它会实际testing以查看用户是否在Vista或更高版本。 那样的话,如果一个客户在几年前没有框架或beta框架的情况下使用XP,它将允许你改变你想要做的事情。
然后它将进行物理testing,以避免该帐户的空值。
最后,它将提供检查以validation用户是否确实处于适当的angular色。
我知道这个问题已经回答了, 但是我认为我的解决scheme对于searchStack的其他人来说是一个很好的补充。 我在Protected构造函数背后的推理将允许您将此类用作派生类,您可以控制何时实例化类的状态。
您也可以调用Windows API来执行此操作:
[DllImport("shell32.dll", SetLastError=true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool IsUserAnAdmin();
这更一般地告诉你用户是否在提升的权限下运行。
上面IsInRole的答案其实是正确的:它确实检查当前用户是否具有pipe理员权限。 然而,
从Windows Vista开始,用户帐户控制(UAC)确定用户的权限。 如果您是内置pipe理员组的成员,则会为您分配两个运行时访问令牌:标准用户访问令牌和pipe理员访问令牌。 默认情况下,您处于标准用户angular色。
(来自MSDN,例如https://msdn.microsoft.com/en-us/library/system.diagnostics.eventlogpermission(v = vs.110 ) .aspx )
因此, IsInRole将默认考虑用户权限,因此该方法返回false。 只有当软件以pipe理员身份明确运行时才是如此。
另一种检查https://ayende.com/blog/158401/are-you-an-administrator中的; AD的方法将检查用户名是否在pipe理员组中。
我完整的方法是:
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; }
对于没有提升权限的pipe理组中的用户(启用UAC),此方法IsCurrentUserAdmin()返回!checkCurrentRole:如果checkCurrentRole == false,则为true;如果checkCurrentRole == true,则为false
如果您运行的代码需要pipe理员权限,请考虑checkCurrentRole == true。 否则,到那时你将会得到一个安全例外。 因此正确的IsInRole逻辑。
我必须确定运行它们的用户是pipe理员
如果您的应用程序必须以pipe理员权限运行,则更新其清单是正确的。
将requestedExecutionlevel
设置为requireAdminstrator
。