【问题标题】:check if user is a member of a group检查用户是否是组的成员
【发布时间】:2012-03-20 19:02:02
【问题描述】:

我有一个代码来检查用户是否是组的成员。 我在登录时使用它。

请注意我有一个域用户和本地用户,例如。 testdomain\administratoradministrator

这是我使用的代码:

using (DirectoryEntry groupEntry = new DirectoryEntry("WinNT://./" + userGroupName + ",group"))
{
    foreach (object member in (IEnumerable)groupEntry.Invoke("Members"))
    {
        using (DirectoryEntry memberEntry = new DirectoryEntry(member))
        {
            string completeName = memberEntry.Name;
            DirectoryEntry domainValue = GUIUtility.FindDomain(memberEntry);
            if (domainValue != null)
            {
                completeName = domainValue.Name + "\\" + memberEntry.Name;
            }
            Global.logger.Info("completeName from " + userGroupName + " = " + completeName);
            if (userName.Equals(completeName, StringComparison.InvariantCultureIgnoreCase))
            {
                Global.logger.Debug("IsUserPartOfWindowsGroup returned True with username =" + userName + " , UserGroupName = " + userGroupName);
                return true;
            }
        }
    }
    Global.logger.Debug("IsUserPartOfWindowsGroup returned false for username =" + userName + " , UserGroupName = " + userGroupName);
    return false;
}

这段代码有效,但是

DirectoryEntry domainValue = GUIUtility.FindDomain(memberEntry);

在我看来,在分析器中花费了很多时间。有没有更好/更快的方法来处理这个问题?

public static DirectoryEntry FindDomain(DirectoryEntry memberEntry)
{
    if (memberEntry.Parent != null)
    {
        if (memberEntry.Parent.SchemaClassName.Equals("domain", StringComparison.InvariantCultureIgnoreCase))
        {
            return memberEntry.Parent;
        }
    }
    return null;
}

另一种方式:

DirectoryEntry entry = new DirectoryEntry("LDAP://" + domain, userName, Password);
DirectorySearcher mySearcher = new DirectorySearcher(entry);
mySearcher.Filter = "(&(objectClass=user)(|(cn=" + userName + ")(sAMAccountName=" + userName + ")))";
SearchResult result = mySearcher.FindOne();

Global.logger.Info("result == " + result.Path);
foreach (string GroupPath in result.Properties["memberOf"])
{
    if (GroupPath.Contains(adminGroupName))
    {
        Global.logger.Info(compUsrNameForEncryption + "exists in " + adminGroupName);
    }
}

【问题讨论】:

  • 如果我们知道GUIUtility.FindDomain 是什么,我们可能会提供更好的帮助。此外,新的(ish)System.DirectoryServices.AccountManagement 类使这类事情变得更加简单。
  • Related questionmy answer 中的代码可能也会对您有所帮助。
  • 嘿 babcock.. 我添加了 finddomain 功能。如果用户不属于域怎么办?
  • 您确定 FindDomain 是什么在消耗您的周期吗?它并没有真正做任何事情。
  • 不是域的一部分,这意味着他们只是本地用户?

标签: c# asp.net windows login active-directory-group


【解决方案1】:

这与我使用的非常接近:

public bool IsUserInGroup(string userName, string groupName)
{
    using (var context = new PrincipalContext(ContextType.Machine))
    {
        using (var searcher = new PrincipalSearcher(new UserPrincipal(context) { SamAccountName = userName }))
        {
            using (var user = searcher.FindOne() as UserPrincipal)
            {
                return user != null && user.IsMemberOf(context, IdentityType.SamAccountName, groupName);
            }
        }
    }
}

不过,我还没有为本地用户测试过它。该逻辑在我的域中有效,我刚刚更改了PrincipalContext(ContextType.Machine),所以它现在应该查看本地用户。

别忘了为System.DirectoryServices.AccountManagement添加引用和使用语句

【讨论】:

  • 嘿,我得到一个错误 nullrefrenceexception 在:return user.IsMemberOf(context, IdentityType.SamAccountName, groupName);
  • 我还删除了所有健全性检查,因此如果 userName 不是有效用户,您就会知道。
  • 我的原始代码缺少一些usings,所以我添加了它们并进行了必要的健全性检查。
  • 我试过了,但它说用户不属于该组..基本上用户值是空的...我将用户名作为域\用户名..
  • 您不需要使用 domain\ 部分。用户名应该足够了(反正我就是这么用的)。
【解决方案2】:

也许我错过了什么,但你不能这样做:

if(Page.User.IsInRole("GROUP NAME"))
{
    // user is in group. do your thing
}
else
{
    // user isn't in group
}

当我在 ASP.NET 上进行 Active Directory 身份验证时为我工作。

编辑:这是一个 link 描述使用 Page.User.IsInRole()。但是必须使用 Windows 身份验证,如果不使用 Windows 身份验证,它将无法正常工作。

EDIT2:由于没有使用 Windows 身份验证,我将这样做:

DirectoryEntry de = new DirectoryEntry(LDAP Address,user,password);
DirectorySearcher searcher = new DirectorySearcher(de);
searcher.Filter = string.Format("(SAMAccountName={0})", user);
SearchResult result = searcher.FindOne();
bool isInGroup = false;
if (result != null)
{
    DirectoryEntry person = result.GetDirectoryEntry();
    PropertyValueCollection groups = person.Properties["memberOf"];
    foreach (string g in groups)
    {
        if(g.Equals(groupName))
        {
           isInGroup = true;
           break;
        }
    }
}
return isInGroup;

【讨论】:

  • 您可能是对的,但我不是 ASP.NET 开发人员。 OP 确实说他们正在寻找一种适用于本地用户/组的解决方案,但如果您的解决方案适用于该解决方案,那么您的答案可能是最好的。
  • @M.Babcock 只要 OP 使用 Windows 身份验证,那么这将起作用。如果没有,那么你的答案就是要走的路
  • 我不使用windows身份验证..这是在一个类中定义的..所以页面不会工作..谢谢
  • @user175084 我已编辑我的回复以反映新信息
  • 嘿,我已经尝试过此代码.. 如果我提供域用户,这将有效.. 但是对于本地用户它将如何工作.. 原因是我无法弄清楚 LDAP 路径? ?
猜你喜欢
  • 2011-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-27
  • 1970-01-01
  • 1970-01-01
  • 2019-06-27
相关资源
最近更新 更多