【问题标题】:Determine if user can obtain admin privileges if needed如果需要,确定用户是否可以获得管理员权限
【发布时间】:2017-09-21 04:23:08
【问题描述】:

我有一个内部 C# 应用程序,它将在多个远程位置的笔记本电脑上运行。最常见的用户将拥有笔记本电脑的管理员权限,但有时它会由没有管理员权限的用户运行。出于操作原因,我们希望每台计算机只需要一份应用程序副本,因此它将安装在 Program Files 下而不是用户帐户下。

我正在创建一个自动更新例程。我希望它有这种行为:

  1. 它会检查是否有可用的更新。
  2. 如果有更新且用户没有管理员权限,则会通知他们更新。
  3. 如果用户具有管理员权限,则会加载更新。
  4. 在所有情况下,都会启动应用程序。非管理员用户可以决定是否需要关闭更新并找到具有管理员权限的人。

99% 的时间不会有更新,而且我不希望在通常不需要的情况下在清单中请求权限。所以我计划开始一个单独的过程来实际加载更新。但在这种情况下,我宁愿不打扰非管理员用户请求他们无法提供的管理员权限(不 - 他们不会有另一个他们自己可以登录的具有管理员权限的帐户)。

是否有一些可靠的方法可以让它确定 - 一旦它找到更新 - 当前用户是否在管理员组中,以便它知道是否需要启动更新过程,或者只是报告可用的更新和继续?

我已经搜索了几个小时,但只找到了一种方法(检查用户是否有拆分令牌)显然不可靠并被警告。

编辑:

为了完整起见,我根据 Wheels73 的帖子找到的最终解决方案是:

  bool CurrentUserIsAdmin() 
  {
     UserPrincipal user = UserPrincipal.Current;
     using (IEnumerator<Principal> groups = user.GetAuthorizationGroups().GetEnumerator()) 
     {
        while (groups.MoveNext()) 
        {
           try 
           {
              if (groups.Current.ToString() == "Administrators") 
              {
                 return true;
              }
           } 
           catch (NoMatchingPrincipalException) 
           {
              continue;
           }
        }
        return false;
     }
  }

【问题讨论】:

  • 您能否查询 windows Active Directory Group 以查看您的用户所在的组?
  • 我不知道。我可以吗?这就是我要问的。
  • 这就是你说的不靠谱的方法吗? stackoverflow.com/a/10045269/5226582
  • @PaulSinclair - 你可以。我问不是每个人都使用 AD。向 System.DirectoryServices 添加一个引用。您创建一个新的 DirectorySearcher 并在用户窗口中登录以进行搜索。
  • @Wheels73 - 谢谢。我有点太鲁莽了。我不熟悉 Active Directory 组,并根据您的评论开始研究它。我非常感谢您的建议。

标签: c# uac


【解决方案1】:

如前所述,这是我用来列出给定登录名的所有 AD 目录的例程。

 public List<string> GetUsersActiveDirectoryGroups(string windowsUserName)
 {
            var allUserGroups = new List<string>();
            var domainConnection = new DirectoryEntry();

            var samSearcher = new DirectorySearcher
            {
                SearchRoot = domainConnection,
                Filter = "(samAccountName=" + windowsUserName + ")"
            };
            samSearcher.PropertiesToLoad.Add("displayName");

            var samResult = samSearcher.FindOne();

            if (samResult == null) //User not found
                return allUserGroups;

            //Get groups
            var theUser = samResult.GetDirectoryEntry();
            theUser.RefreshCache(new[] {"tokenGroups"});

            foreach (byte[] resultBytes in theUser.Properties["tokenGroups"])
            {
                var mySid = new SecurityIdentifier(resultBytes, 0);

                var sidSearcher = new DirectorySearcher
                {
                    SearchRoot = domainConnection,
                    Filter = "(objectSid=" + mySid.Value + ")"
                };
                sidSearcher.PropertiesToLoad.Add("name");

                var sidResult = sidSearcher.FindOne();
                if (sidResult != null)
                {
                    allUserGroups.Add(sidResult.Properties["name"][0].ToString());
                }
            }

            return allUserGroups;
}

然后您可以检查组的内容,以根据您要查找的组名称返回一个布尔值。

 var myUsersGroups = GetUsersActiveDirectoryGroups("YOURLOGINNAME");
 var usersIsInAdmin = myUsersGroups.Any(g => g == "Administrator");

要检测用户是否仅具有本地管理员权限,您可以使用以下方法

            WindowsIdentity user = null;

            user = WindowsIdentity.GetCurrent();
            var principal = new WindowsPrincipal(user);
            var isAdmin = principal.IsInRole(WindowsBuiltInRole.Administrator);

好的..最后的呐喊:)

要查看其他用户是否具有本地管理员权限,您可以执行以下操作

var usersPrincipal = UserPrincipal.FindByIdentity(UserPrincipal.Current.Context, IdentityType.SamAccountName, "YOURLOGINNAME");
var otherUserIsAdmin = usersPrincipal.GetAuthorizationGroups().Any(p => p.ToString() == "Administrators");

希望对您有所帮助。

【讨论】:

  • 谢谢。但是在测试中,即使我可以检查并且我确实在我的桌面上拥有管理权限,但这并没有为我列出任何远程命名的组,例如“管理员”。
  • 你好..对不起..这只是一个例子。您需要知道为您的域用户提供您正在寻找的管理员权限的组的名称。
  • 相关权限是本地机器的管理权限。要将这些权限授予其他人,我需要做的就是在“管理用户帐户”下,选择一个用户,打开属性,然后单击“管理员”选项。我不必将它们分配给某个自定义命名的组。因此,似乎有一些标准化的方法可以识别这一点。也许本地管理员权限不是通过 Active Directory 组获得的?
  • 啊,我明白了。我在答案的底部添加了额外内容。这应该可以满足您的需要。
  • 仅供参考 - this was the cause,以及治愈方法。
猜你喜欢
  • 2016-02-24
  • 2015-06-20
  • 1970-01-01
  • 1970-01-01
  • 2011-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多