Расширенные принципы пользователя C#

Моя организация использует комбинацию AD и LDS. AD синхронизируется с LDS и сохраняет некоторую информацию в полях extensionAttribute [в основном, 10, 11 и 12].

Я могу получить стандартную информацию в порядке от LDS, то есть Title, Surname, Initials, но не могу получить exntensionAttributes. Я использовал этот пример для расширения UserPrincipal, но все еще не могу увидеть значения атрибута.

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

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

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

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

        [DirectoryProperty("extensionAttribute10")]
        public string Ext10
        {
            get
            {
                if (ExtensionGet("extensionAttribute10").Length != 1)
                    return null;
                return (string)ExtensionGet("extensionAttribute10")[0];
            }
        }
    }

Тогда у меня есть:

PrincipalContext ctx = new PrincipalContext(ContextType.ApplicationDirectory, "LDSServerHere:389", "OU HERE", "Acccount Name Here", "Password HEre");

        UserPrincipalEx u = UserPrincipalEx.FindByIdentity(ctx, IdentityType.SamAccountName, login);
        string prop = string.Empty;
        try
        {
            prop = u.Ext10;
        }
        catch (Exception ex)
        {
            prop = ex.ToString();
        }

        return prop;

Продолжайте получать исключение NULLReferenceException: ссылка на объект не установлена ​​на экземпляр объекта

Я делаю что-то глупое здесь?

1 ответ

Призвание FindByIdentityWithType не сработает Глядя на документацию, она унаследована от Principal (не UserPrincipal) и он говорит, что "не предназначен для вызова непосредственно из вашего кода". Скорее всего, он просто не понимает ваш производный класс, поэтому ничего не возвращает, потому что ничего не находит в вашем классе.

Но есть и другой способ сделать это: использовать DirectoryEntry,

PrincipalContext ctx = new PrincipalContext(ContextType.ApplicationDirectory, "LDSServerHere:389", "OU HERE", "Acccount Name Here", "Password HEre");

UserPrincipal u = UserPrincipal.FindByIdentity(ctx, IdentityType.SamAccountName, login);
string prop = string.Empty;

try
{
    var de = (DirectoryEntry) u.GetUnderlyingObject();
    if (de.Properties.Contains("extensionAttribute10")) {
        prop = de.Properties["extensionAttribute10"].Value;
    }
}
catch (Exception ex)
{
    prop = ex.ToString();
}

return prop;

Обратите внимание на нулевую проверку свойства. Если атрибут пуст, он не будет существовать в Properties Коллекция на всех. Вы могли бы, вероятно, добавить туда несколько дополнительных нулевых проверок просто для безопасности.

UserPrincipal и другие занятия в AccountManagement Пространство имен просто использовать DirectoryEntry на заднем плане в любом случае. Они просто не раскрывают все доступные атрибуты. Так что иногда вы должны использовать DirectoryEntry непосредственно.

На самом деле, я обнаружил, что гораздо быстрее и эффективнее использовать только DirectoryEntry и не использовать AccountManagement пространство имен вообще, хотя иногда это может быть немного сложнее в использовании.

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