Поиск в Active Directory не получает ссылку на объект - PullRequest
2 голосов
/ 11 июля 2011

Приведенный ниже код работает на моем локальном компьютере, возвращая полное имя пользователя из Active Directory:

string principal = System.Web.HttpContext.Current.Request.LogonUserIdentity.Name.Remove(0, 12);

string filter = string.Format("(&(ObjectClass={0})(sAMAccountName={1}))", "person", principal);

string[] properties = new string[] { "fullname" };

DirectoryEntry adRoot = new DirectoryEntry("LDAP://myserver.com");
adRoot.AuthenticationType = AuthenticationTypes.Secure;

DirectorySearcher searcher = new DirectorySearcher(adRoot);

searcher.SearchScope = SearchScope.Subtree;

searcher.ReferralChasing = ReferralChasingOption.All;

searcher.PropertiesToLoad.AddRange(properties);

searcher.Filter = filter;

SearchResult result = searcher.FindOne();

DirectoryEntry directoryEntry = result.GetDirectoryEntry();

string displayName = directoryEntry.Properties["displayName"][0].ToString();

if (string.IsNullOrEmpty(displayName) == false)
{
    return displayName;
}

Когда я публикую его на сервере разработки, я получаю следующую ошибку:

System.NullReferenceException: ссылка на объект не установлена ​​для экземпляра объекта.

Ошибка выдается в следующей строке:

DirectoryEntry directoryEntry = result.GetDirectoryEntry();

Я пробовал

DirectoryEntry adRoot = new DirectoryEntry("LDAP://" + domain, AdAdminUsername, AdAdminPassword, AuthenticationTypes.Secure);

но все равно нет радости.

Есть идеи?

Спасибо!

Ответы [ 2 ]

1 голос
/ 11 июля 2011

Только снаружи: ваша строка с именем principal состоит из следующих элементов:

string principal = System.Web.HttpContext.Current.Request.LogonUserIdentity.Name.Remove(0, 12);

Вы входили в систему 'System.Web.HttpContext.Current.Request.LogonUserIdentity.Name 'на своем сервере разработки? Эта статическая конструкция может быть причиной ваших неприятностей, потому что если principal не то, что вы думаете, результатом FindOne может быть NULL.

1 голос
/ 11 июля 2011

В вашем текущем коде вы должны проверить NULL после вызова FindOne() - он может вернуть значение NULL, если не найдена соответствующая запись в каталоге.

См. Документы MSDN :

Если во время поиска найдено более одной записи, возвращается только первая запись. Если не найдено записей, соответствующих критериям поиска, возвращается нулевая ссылка (Ничего в Visual Basic).

Плюс, вы также должны всегда проверяйте на наличие свойства перед доступом к нему - оно может отсутствовать .....

Следовательно, ваш код должен выглядеть примерно так:

SearchResult result = searcher.FindOne();

if(result != null)
{
    DirectoryEntry directoryEntry = result.GetDirectoryEntry();

    if(directoryEntry.Properties["displayName"] != null &&
       directoryEntry.Properties["displayName"].Length > 0)
    {
       string displayName = directoryEntry.Properties["displayName"][0].ToString();

       if (!string.IsNullOrEmpty(displayName))
       {
          return displayName;
       }
    }
}

Но: если вы работаете в .NET 3.5 или новее, вы должны проверить пространство имен System.DirectoryServices.AccountManagement, которое значительно упрощает работу с Active Directory.

Вы можете использоватьPrincipalSearcher и принцип «запрос за примером» для поиска:

// create your domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);

// define a "query-by-example" principal - here, we search for a UserPrincipal 
// and with the first name (GivenName) of "Bruce"
UserPrincipal qbeUser = new UserPrincipal(ctx);
qbeUser.SamAccountName = "whatever you're looking for.....";

// create your principal searcher passing in the QBE principal    
PrincipalSearcher srch = new PrincipalSearcher(qbeUser);

// find all matches
foreach(var found in srch.FindAll())
{
    // do whatever here - "found" is of type "Principal" - it could be user, group, computer.....          
}

Если вы еще этого не сделали - обязательно прочитайте статью MSDN Управление принципами безопасности каталога в.NET Framework 3.5 , которая показывает, как наилучшим образом использовать новые функции в System.DirectoryServices.AccountManagement

. Конечно, в зависимости от ваших потребностей, вы можете указать другие свойства для этого запросапример пользователя, которого вы создаете:

  • Surname (или фамилия)
  • DisplayName (обычно: имя + пробел + фамилия)
  • SAM Account Name - имя вашей учетной записи Windows / AD
  • User Principal Name - ваше имя в стиле «username@yourcompany.com»

Вы можете указать любое из свойств в UserPrincipal и использовать их в качестве «запроса по примеру» для вашегоPrincipalSearcher.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...