如何检查用户是属于AD组还是嵌套组?

Int*_*gue 5 .net asp.net active-directory windows-authentication

我有一个使用Windows身份验证的ASP.NET 3.5应用程序并实现我们自己的RoleProvider.

问题是我们想要将对一组页面的访问限制为几千个用户,而不是逐个输入所有这些页面,我们发现它们属于一个AD组.

答案很简单,如果我们检查特定用户的成员资格的公共组是它的直接成员,但我遇到的问题是,如果该组是另一个组的成员,然后是另一个组的成员,那么我的代码总是返回false.

例如:假设我们要检查User是否是E组的成员,但是User不是*E"的直接成员,她是"A"的成员,其中"B"的成员确实是其成员E,因此用户是*E的成员

我们的解决方案之一非常缓慢,尽管它给出了正确的答案

using (var context = new PrincipalContext(ContextType.Domain))
  {
    using (var group = GroupPrincipal.FindByIdentity(context, IdentityType.Name, "DL-COOL-USERS"))
    {
      var users = group.GetMembers(true); // recursively enumerate

      return users.Any(a => a.Name == "userName");
    }
  }
Run Code Online (Sandbox Code Playgroud)

原始解决方案以及我尝试使用.NET 3.5 System.DirectoryServices.AccountManagement工作,当用户是相关组的直接成员时,它确实有效,如下所示:

public bool IsUserInGroup(string userName, string groupName)
{
  var cxt = new PrincipalContext(ContextType.Domain, "DOMAIN");
  var user = UserPrincipal.FindByIdentity(cxt, IdentityType.SamAccountName, userName);

 if (user == null)
  {       
    return false;
  }


  var group = GroupPrincipal.FindByIdentity(cxt, groupName);

  if (group == null)
  {        
    return false;
  }

  return user.IsMemberOf(group);
}
Run Code Online (Sandbox Code Playgroud)

最重要的是,我们需要检查成员资格,即使这些组嵌套在很多级别中.

非常感谢!

Int*_*gue 1

好吧,我不得不跳出这个框架来思考,幸运的是,通过研究 AD,我们发现所有 3000 多名必须查看这些页面的人在自定义 AD 属性中共享一个关键字。所以我所要做的就是从 AD 加载对象并查找它。最终的效果客户非常满意!目前这似乎是一个有点肮脏的解决方案,但一如既往,它工作得很好,我们必须继续做其他事情!

目前,我们正在进行试点计划,我们希望出现任何错误并得到通知,以便我们采取行动。

public static bool IsEmployeeCoolEnoughToSeePages(string userName)
{
  if (string.IsNullOrEmpty(userName))
  {
    throw new ArgumentNullException("Current user's Username cannot be null");
  }

  using (var searcher = new DirectorySearcher(("LDAP://YOURDOMAIN.com")))
  {
    searcher.Filter = string.Format("(&(objectCategory=user)(samAccountName={0}))", ariseUserName);
    SearchResultCollection searchResultCollection = searcher.FindAll();

    if (searchResultCollection.Count == 1)
    {
      var values = searchResultCollection[0].Properties["title"];

      if (values.Count == 1)
      {
        return values[0].ToString().StartsWith("_COOLNES_");
      }
    }

    return false;
  }
}
Run Code Online (Sandbox Code Playgroud)