проверить, является ли пользователь членом группы - PullRequest
1 голос
/ 20 марта 2012

У меня есть код, чтобы проверить, является ли пользователь членом группы.Я использую это при входе в систему.

Обратите внимание, что у меня есть пользователь домена и локальный пользователь, например.testdomain\administrator и administrator.

Этот код я использую:

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);
    }
}

Ответы [ 2 ]

8 голосов
/ 20 марта 2012

Это довольно близко к тому, что я использую:

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

1 голос
/ 20 марта 2012

Может быть, я что-то упустил, но вы не могли просто сделать:

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

Работает для меня, когда я делаю проверку подлинности Active Directory в ASP.NET.

РЕДАКТИРОВАТЬ:Вот ссылка , описывающая использование 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;
...