Расширения UserPrincipal возвращают компьютеры

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

Библиотека находится в .NetStandard 2.0, и я использую основные классы из

System.DirectoryServices.AccountManagement

Поскольку класс UserPrincipal не содержит всех свойств, которые нам могут понадобиться, я попытался реализовать класс UserPrincipalExtended, который на данный момент просто добавляет свойство Initials.

Вот мой класс:

[DirectoryObjectClass("user")]
[DirectoryRdnPrefix("CN")]
public class UserPrincipalExtended : UserPrincipal
{
    public UserPrincipalExtended(PrincipalContext context) : base(context) { }

    public UserPrincipalExtended(PrincipalContext context, string samAccountName, string password, bool enabled) : base(context, samAccountName, password, enabled) { }

    [DirectoryProperty("Initials")]
    public string Initials
    {
        get
        {
            if (ExtensionGet("initials").Length != 1) return null;

            return (string)ExtensionGet("initials")[0];

        }
        set { ExtensionSet("initials", value); }
    }

    public static new UserPrincipalExtended FindByIdentity(PrincipalContext context, string identityValue)
    {
        return (UserPrincipalExtended)FindByIdentityWithType(context, typeof(UserPrincipalExtended), identityValue);
    }

    public static new UserPrincipalExtended FindByIdentity(PrincipalContext context, IdentityType identityType, string identityValue)
    {
        return (UserPrincipalExtended)FindByIdentityWithType(context, typeof(UserPrincipalExtended), identityType, identityValue);
    }
}

Когда я выполняю поиск в активном каталоге с помощью класса UserPrincipal, он работает так, как ожидалось:

using (var context = _contextProvider.GetPrincipalContext())
using (var query = new UserPrincipal(context))
using (var searcher = new PrincipalSearcher(query))
{
    foreach (var principal in searcher.FindAll())
    {
        UserPrincipal userPrincipal = principal as UserPrincipal;

        if (CheckHelper.IsFilled(userPrincipal))
        {
            Console.WriteLine($"{userPrincipal.StructuralObjectClass} : {userPrincipal.SamAccountName}");
        }
    }
}

/*Output
user : cadmin
user : Guest
user : DefaultAccount
*/

Но если я попытаюсь выполнить тот же поиск, используя свой собственный класс, результат также будет содержать компьютеры:

using (var context = _contextProvider.GetPrincipalContext())
using (var query = new UserPrincipalExtended(context))
using (var searcher = new PrincipalSearcher(query))
{
    foreach (var principal in searcher.FindAll())
    {
        UserPrincipalExtended userPrincipalExtended = principal as UserPrincipalExtended;

        if (CheckHelper.IsFilled(userPrincipalExtended))
        {
            Console.WriteLine($"userPrincipalExtended.StructuralObjectClass} : {userPrincipalExtended.SamAccountName}");
        }
    }
}
/*Output
user : cadmin
user : Guest
user : DefaultAccount
computer : WS001$
computer : WS002$
computer : WS003$
*/

Поскольку мой класс UserPrincipalExtended имеет атрибут:

[DirectoryObjectClass("user")]

Я думал, что этого достаточно для фильтрации по этому типу объекта в активном каталоге, но, похоже, это не так.

Любая идея о том, что здесь происходит?

Ваше здоровье


person Papapinguy    schedule 30.08.2018    source источник
comment
computer наследуется от user в стандартной схеме каталога AD. Все компьютеры являются пользователями.   -  person Damien_The_Unbeliever    schedule 30.08.2018
comment
Но тогда почему они не возвращаются, когда я выполняю поиск с помощью UserPrinicpal? Почему поведение отличается, так как я расширяю этот класс?   -  person Papapinguy    schedule 30.08.2018
comment
Microsoft не публикует соответствующий исходный код, referencesource.microsoft.com/#q=system.directoryservices так что вам придется копать это с помощью декомпилятора.   -  person Lex Li    schedule 30.08.2018
comment
В своем классе вы используете UserPrincipalExtended. В примере поиска в активном каталоге вы используете UserPrincipal. Таким образом, вы не пытаетесь выполнить тот же поиск, как вы сказали.   -  person Theo    schedule 02.09.2018


Ответы (2)


В вашем конструкторе вы можете установить для атрибута ObjectCategory значение User

[DirectoryObjectClass("user")]
[DirectoryRdnPrefix("CN")]
public class UserPrincipalExtended : UserPrincipal
{
    public UserPrincipalExtended(PrincipalContext context) : base(context)
    {
        // Set ObjectCategory to user so computer objects are not returned
        ExtensionSet("objectCategory", "user");
    }

    [DirectoryProperty("Initials")]
    public string Initials
    {
        get
        {
            if (ExtensionGet("initials").Length != 1) return null;
            return (string)ExtensionGet("initials")[0];
        }
        set { ExtensionSet("initials", value); }
    }
}
person mheptinstall    schedule 05.10.2019

Майкрософт основные типы фильтров создают код

Тоже столкнулся с этой проблемой. Порывшись в исходниках, нашел такой обходной путь.

[DirectoryObjectClass("user)(objectCategory=user")]
person Stepan    schedule 27.01.2019