Проверьте членство в Active Directory.

Как мне выполнить итерацию группы, чтобы узнать, является ли данный пользователь членом группы?

Я знаю, что могу использовать IsInRole для объекта WindowsPrincipal, но по какой-то причине он не всегда работает для меня, он не выдает ошибку или не выдает исключение, а просто возвращает false.

Я собрал следующий код из Интернета, может ли он помочь мне улучшить его с точки зрения надежности, он не дал неправильного результата за 3 недели тестирования.

Примечания: 1: У меня нет доступа к имени пользователя и паролю AD, поэтому я использую GC. 2: Группы могут быть созданы в любом домене, но в одном лесу. 3: Группа может иметь пользователей из разных доменов, а также групп.

Спасибо

KA

    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
    static extern int CheckTokenMembership(int TokenHandle, byte[] PSID, out bool IsMember);

   [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
    static extern bool IsValidSid(byte[] PSID);


private bool Authenticate(XmlNodeList XmlNodeGroups)
    {
        bool result = false;
        try
        {
            Dictionary<string, List<string>> Groups = GetGroups(XmlNodeGroups);
            //search global catalog and get SID of the group
            Byte[] sid = null;
            foreach (string groupName in Groups.Keys)
            {
                using (DirectoryEntry entry = new DirectoryEntry("GC:"))
                {
                    IEnumerator ie = entry.Children.GetEnumerator();
                    ie.MoveNext();
                    using (DirectorySearcher ds = new DirectorySearcher((DirectoryEntry)ie.Current))
                    {
                        ds.Filter = string.Format("(&(|(sAMAccountName={0}))(objectClass=group))", groupName);  
                        using (SearchResultCollection resColl = ds.FindAll())
                        {
                            if (resColl.Count > 0)
                            {
                                ResultPropertyCollection resultPropColl = resColl[0].Properties;
                                sid = (byte[])resultPropColl["objectsid"][0];
                                if (sid == null || !IsValidSid(sid))
                                {
                                    // log message and continue to next group                                        continue;
                                }
                            }
                            else
                            {
                                  // log message and continue to next group                                    continue;
                            }
                        }

                        bool bIsMember = false;
                        if (CheckTokenMembership(0, sid, out bIsMember) == 0)
                        {
                               // log message and initiate fall back....... use Legacy
                            result = CheckMemberOf(XmlNodeGroups, _CurrentIdentity);
                            break;
                        }
                        else
                        {
                            result = bIsMember ? true : false;
                            if (result)
                            {
                                // debug message                                    break;
                            }
                            else
                            {
                               // debug message
                            }
                        }
                    }
                }
            }
        }
        catch (Exception ex)
        {
            // log exception message and initiate fall back....... use Legacy
            result = CheckMemberOf(XmlNodeGroups, _CurrentIdentity);
        }
        return result;
    }</code>

2 ответа

Решение

Вы на.NET 3.5? Если это так, ознакомьтесь со статьей в журнале MSDN Управление принципами безопасности каталогов в.NET Framework 3.5. Он показывает, насколько проще стало, когда дело доходит до пользователей и групп в AD.

Что касается вашего требования - вы могли бы

  • найти группу, о которой идет речь
  • перечислить всех своих членов
  • определить, является ли данный пользователь членом этой группы

и все это может быть сделано довольно легко с помощью System.DirectoryServices.AccountManagement Пространство имен:

// establish a context - define a domain (NetBIOS style name),  
// or use the current one, when not specifying a specific domain
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);

// find the group in question
GroupPrincipal theGroup = GroupPrincipal.FindByIdentity(ctx, "nameOfGroup");

// recursively enumerate the members of the group; making the search
// recursive will also enumerate the members of any nested groups
PrincipalSearchResult<Principal> result = theGroup.GetMembers(true);

// find the user in the list of group members
UserPrincipal user = (result.FirstOrDefault(p => p.DisplayName == "Some Name") as UserPrincipal);

// if found --> user is member of this group, either directly or recursively
if(user != null)
{
     // do something with the user
}

Я попытался использовать ваш фрагмент кода выше для фреймворка 3.5 и эта строка моего компилятора говорит, что это неверно:

    // find the user in the list of group members
    UserPrincipal user = (result.FirstOrDefault(p => p.DisplayName == adUser) as UserPrincipal);

В частности, результат.FirstOfDefault говорит, что это недопустимый вариант.

Спасибо!

Другие вопросы по тегам