一尘不染

如何在Active Directory中获取用户组?(C#,asp.net)

c#

我使用此代码来获取当前用户的组。但是我想手动给用户,然后得到他的组。我怎样才能做到这一点?

using System.Security.Principal;

public ArrayList Groups()
{
    ArrayList groups = new ArrayList();

    foreach (IdentityReference group in System.Web.HttpContext.Current.Request.LogonUserIdentity.Groups)
    {
        groups.Add(group.Translate(typeof(NTAccount)).ToString());
    }

    return groups;
}

阅读 373

收藏
2020-05-19

共1个答案

一尘不染

如果您使用的是.NET
3.5或更高版本,则可以使用新的System.DirectoryServices.AccountManagement(S.DS.AM)名称空间,这比以前更容易了。

在这里阅读有关它的所有信息: 在.NET Framework 3.5中管理目录安全性主体

更新: 不幸的是,较早的MSDN杂志文章不再在线上-您需要从Microsoft
下载2008年1月MSDN杂志的CHM并在其中阅读该文章。

基本上,您需要有一个“主要上下文”(通常是您的域),一个用户主体,然​​后您可以非常容易地获得其组:

public List<GroupPrincipal> GetGroups(string userName)
{
   List<GroupPrincipal> result = new List<GroupPrincipal>();

   // establish domain context
   PrincipalContext yourDomain = new PrincipalContext(ContextType.Domain);

   // find your user
   UserPrincipal user = UserPrincipal.FindByIdentity(yourDomain, userName);

   // if found - grab its groups
   if(user != null)
   {
      PrincipalSearchResult<Principal> groups = user.GetAuthorizationGroups();

      // iterate over all groups
      foreach(Principal p in groups)
      {
         // make sure to add only group principals
         if(p is GroupPrincipal)
         {
             result.Add((GroupPrincipal)p);
         }
      }
   }

   return result;
}

这就是全部!现在,您可以获得用户所属的授权组的结果(列表)-遍历它们,打印出它们的名称或您需要执行的任何操作。

更新: 为了访问某些未显示在UserPrincipal对象上的属性,您需要深入研究底层内容DirectoryEntry

public string GetDepartment(Principal principal)
{
    string result = string.Empty;

    DirectoryEntry de = (principal.GetUnderlyingObject() as DirectoryEntry);

    if (de != null)
    {
       if (de.Properties.Contains("department"))
       {
          result = de.Properties["department"][0].ToString();
       }
    }

    return result;
}

更新#2: 似乎应该不难将这两个代码片段放在一起....但是好吧-事情就这样了:

public string GetDepartment(string username)
{
    string result = string.Empty;

    // if you do repeated domain access, you might want to do this *once* outside this method, 
    // and pass it in as a second parameter!
    PrincipalContext yourDomain = new PrincipalContext(ContextType.Domain);

    // find the user
    UserPrincipal user = UserPrincipal.FindByIdentity(yourDomain, username);

    // if user is found
    if(user != null)
    {
       // get DirectoryEntry underlying it
       DirectoryEntry de = (user.GetUnderlyingObject() as DirectoryEntry);

       if (de != null)
       {
          if (de.Properties.Contains("department"))
          {
             result = de.Properties["department"][0].ToString();
          }
       }
    }

    return result;
}
2020-05-19