Запросить пользовательское свойство LDAP через System.DirectoryServices в C #? - PullRequest
3 голосов
/ 18 декабря 2011

На моем сервере OpenLDAP установлена ​​пользовательская схема LDAP, которая выглядит следующим образом:

attributeType ( 999.0.01
    NAME 'picturePath'
    EQUALITY caseIgnoreMatch
    SUBSTR caseIgnoreSubstringsMatch
    SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1024}
    )

objectClass ( 999.1.01
    NAME 'indieStackTeam'
            DESC 'Team definition for IndieStack'
    SUP groupOfUniqueNames
    STRUCTURAL
            MAY     ( picturePath )
    )

В моем приложении ASP.NET MVC 2 я запрашиваю свойство picturePath примерно так (и подтверждается, что picturePath существует в списке ключей):

this.Picture = properties["picturePath"].Value as string;

Когда я пытаюсь сделать это в .NET 3.5, я получаю следующее исключение:

[COMException (0x8000500c): Unknown error (0x8000500c)]   
    System.DirectoryServices.PropertyValueCollection.PopulateList() +347013
    System.DirectoryServices.PropertyValueCollection..ctor(DirectoryEntry entry, String propertyName) +49   
    System.DirectoryServices.PropertyCollection.get_Item(String propertyName) +150

Однако, когда тот же код выполняется под Mono (на том же сервере, что и OpenLDAP), он работает отлично. Такие клиенты, как LDAPAdmin, также могут правильно прочитать свойство picturePath.

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

К сожалению, неизвестная ошибка не говорит мне много о том, что идет не так, но я нахожу, что .NET-реализация System.DirectoryServices очень ненадежна (вы получаете ту же неизвестную ошибку, если подключаетесь к серверу LDAP с использованием нижнего регистра в 'DC =').

Кто-нибудь имел эту проблему раньше, и если да, то как ее решить?

Ответы [ 2 ]

3 голосов
/ 18 декабря 2011

Необходимо проверить две вещи:

1) действительно ли этот конкретный объект пользователя имеет значение в picturePath?Возможно, вы захотите проверить наличие свойства перед тем, как получить к нему доступ:

if(properties.Contains("picturePath") && properties["picturePath"].Count > 0)
{
   ....
}

2) Если я правильно помню, чтобы получить доступ к настраиваемым атрибутам, вы должны явно обновить кэш для объекта пользователя, прежде чем делать что-либо:

DirectoryEntry de = ......;  // find / assign that DirectoryEntry somehow

de.RefreshCache();  // to load all properties from the directory

или:

de.RefreshCache(new string[] { "picturePath" });  // to just load the "picturePath" attribute

Кроме того: классы в System.DirectoryServices действительно в основном ориентированы на использование против Active Directory - возможны «неожиданности» или незначительные несовместимости, когдаиспользуется против какого-либо другого сервера LDAP - например, OpenLDAP.

0 голосов
/ 19 декабря 2011

Кажется, что .NET LDAP-клиент ожидает правильно сформированный OID для типов атрибутов и классов объектов.

Вы заметите, что я использовал OID формы 999.X.YY, которые, хотя они могут быть синтаксически правильными, обычно не встречаются в реальном мире. Я предполагаю, что клиент LDAP анализирует OID и, поскольку они не соответствуют ожидаемым, выдает ошибку.

Я изменил OID на 1.3.6.1.4.1.40000.1.3.1 и 1.3.6.1.4.1.40000.1.4.1 соответственно (я также подал заявку на PEN, который даст мне назначенный номер вместо «40000») ), обновил схему на сервере и заново создал записи, а клиент LDAP теперь правильно считывает пользовательские атрибуты.

...