【问题标题】:How to check if a user belongs to an AD group?如何检查用户是否属于 AD 组?
【发布时间】:2012-08-15 07:03:56
【问题描述】:

起初我认为下面的代码有效,因为如果我将组设置为“IT”,它会正常运行,因为我的用户名位于 Active Directory 中的 IT 组中。我学到的是,无论我的用户名是否在 IT 组中,它总是返回 true,如果我将其更改为我所在的任何其他组,它返回总是返回 false。任何帮助将不胜感激。

    private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
    {
        // tab control security for admin tab
        bool admin = checkGroup("IT");

        if ((admin == true) && (tabControl1.SelectedTab == tpHistory))
        {
            tabControl1.SelectedTab = tpHistory;
        }
        else if ((admin == false) && (tabControl1.SelectedTab == tpHistory))
        {
            tabControl1.SelectedTab = tpRequests;
            MessageBox.Show("Unable to load tab. You have insufficient privileges.",
                "Access Denied", MessageBoxButtons.OK, MessageBoxIcon.Stop);
        }
    }

    // check active directory to see if user is in Marketing department group
    private static bool checkGroup(string group)
    {
        WindowsIdentity identity = WindowsIdentity.GetCurrent();
        WindowsPrincipal principal = new WindowsPrincipal(identity);
        return principal.IsInRole(group);
    }

【问题讨论】:

    标签: c# .net winforms c#-4.0 active-directory


    【解决方案1】:

    你不能这样做。 您应该查询活动目录。 您可以为 AD 使用包装器。查看http://www.codeproject.com/Articles/10301/Wrapper-API-for-using-Microsoft-Active-Directory-S

    【讨论】:

    • 虽然这种方法获取信息的方法很长,但利用 IIS 提供的 WindowsIdentity 会利用用户配置文件中加载的当前令牌。无需查询 AD 森林/节点即可获取已在本地加载的相同信息。
    【解决方案2】:

    由于您使用的是 .NET 3.5 及更高版本,因此您应该查看 System.DirectoryServices.AccountManagement (S.DS.AM) 命名空间。在此处阅读所有相关信息:

    基本上,您可以定义域上下文并在 AD 中轻松找到用户和/或组:

    // set up domain context
    PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "DOMAINNAME");
    
    // find a user
    UserPrincipal user = UserPrincipal.FindByIdentity(ctx, "SomeUserName");
    
    // find the group in question
    GroupPrincipal group = GroupPrincipal.FindByIdentity(ctx, "YourGroupNameHere");
    
    if(user != null)
    {
       // check if user is member of that group
       if (user.IsMemberOf(group))
       {
         // do something.....
       } 
    }
    

    新的 S.DS.AM 让在 AD 中与用户和组一起玩变得非常容易!

    【讨论】:

    • 我得到 PrincipalOperationException 在 if (user.IsMemberOf(group)) 上未处理。
    • 显然它是 4.0 social.msdn.microsoft.com/Forums/pl-PL/csharplanguage/thread/… 中的一个错误,我通过将 Environment.UserDomainName 添加到原理上下文来修复它。 stackoverflow.com/questions/4518472/… 如果您想将其编辑到您的代码中,我会接受您的回答。非常感谢您的帮助!
    • @osiris355:使用 social.msdn 上该线程中给出的解决方法更新了我的回复。
    • 这是一个很好的指导。为了方便使用 API,我可以将其转换为几行 PowerShell。我已经在this blog post 中记录了它。
    • @marc_s 这仍然是 4/4.5 的最佳方法吗?
    【解决方案3】:

    与@marc_s 示例略有偏差,在Programstatic void Main() 方法中实现:

    DomainCtx = new PrincipalContext( ContextType.Domain , Environment.UserDomainName );
    if ( DomainCtx != null ) {
        User = UserPrincipal.FindByIdentity( DomainCtx , Environment.UserName );
    }
    

    DomainCtxUser 都是在Program 下声明的静态属性

    然后在其他形式中,我只需执行以下操作:

    if ( Program.User.IsMemberOf(GroupPrincipal.FindByIdentity(Program.DomainCtx, "IT-All") )) {
        //Enable certain Form Buttons and objects for IT Users
    
    }
    

    【讨论】:

      【解决方案4】:

      检查当前用户是否在组中

      public bool AuthenticateGroup(string groupfind)
              {
                  var p = new Process();
                  StringBuilder stringbd = new StringBuilder();
                  p.StartInfo.FileName = "cmd.exe";
                  p.StartInfo.Arguments = @"/c gpresult /V";
                  p.StartInfo.CreateNoWindow = true;
                  p.StartInfo.RedirectStandardError = true;
                  p.StartInfo.RedirectStandardOutput = true;
                  p.StartInfo.RedirectStandardInput = false;
                  p.StartInfo.UseShellExecute = false;
                  p.OutputDataReceived += (a, b) => stringbd.AppendLine(b.Data);
                  p.ErrorDataReceived += (a, b) => stringbd.AppendLine(b.Data);
                  p.Start();
                  p.BeginErrorReadLine();
                  p.BeginOutputReadLine();
                  p.WaitForExit();
                  var textfind = stringbd.ToString();
                  int findpoint = textfind.IndexOf("The user is a part of");
                  string findgroup = "";
                  if (findpoint > 0)
                  {
                      findgroup = textfind.Substring(findpoint, textfind.Length - findpoint);
                  }
      
                  return findgroup.Split('\n').ToList().Any(r=>r.Trim().ToLower()==groupfind.Trim().ToLower());
              }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-08
        • 2017-09-25
        • 1970-01-01
        • 2018-07-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多