Как я могу получить номер телефона из Active Directory, используя основной контекст пользователя

Этот код отлично работает для получения номера телефона из Active Directory с использованием имени пользователя и пароля.

    public string GetPhone(string domain, string username, string pwd)
    {
        _path = "LDAP://" + domain;
        string domainAndUsername = domain + @"\" + username;
        DirectoryEntry entry = new DirectoryEntry(_path, domainAndUsername, pwd);
        string telephoneNumber = string.Empty;

        try
        {
            object obj = entry.NativeObject;
            DirectorySearcher search = new DirectorySearcher(entry);

            SearchResult result = search.FindOne();

            var myEntry = result.GetDirectoryEntry();
            telephoneNumber = myEntry.Properties["telephoneNumber"].Value.ToString();
        }
        catch (Exception ex)
        {

            throw new Exception("Error obtaining phone number. " + ex.Message);
        }
        return telephoneNumber;
    }

Однако у меня есть доступ к паролю пользователя только на странице входа. У меня есть созданный пользовательский контекст, хотя он доступен из любого места в приложении (Context.User, который имеет тип System.Security.Principal.IPrincipal)

Таким образом, как я могу получить телефон из Active Directory, используя уже имеющийся объект Context.User?

заранее большое спасибо

Я предполагаю, что это ASP.NET, но .NET Framework или Core?

Gabriel Luci 29.03.2022 17:23

Это .NET Framework

James 29.03.2022 17:34

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

urlreader 29.03.2022 17:56
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
53
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Полученный объект User будет иметь SID пользователя. При этом вы можете использовать путь LDAP привязки SID в DirectoryEntry: LDAP://<SID=XXXXX>

var user = new DirectoryEntry(
    $"LDAP://<SID = {((WindowsIdentity) HttpContext.User.Identity).User.Value}>");

user.RefreshCache(new [] { "telephoneNumber" });
var telephoneNumber = user.Properties["telephoneNumber"]?.Value as string;

Использование RefreshCache заключается в загрузке Только атрибута telephoneNumber. В противном случае, когда вы впервые используете .Properties, он получит атрибут каждый, что является пустой тратой времени и полосы пропускания.

Получение ссылки на объект System.NullReferenceException, не установленной на экземпляр объекта в первой строке :-(

James 29.03.2022 19:09

Используйте отладчик и проверьте, какое значение равно null. Это могут быть HttpContext, HttpContext.User, HttpContext.User.Identity и т. д.

Gabriel Luci 29.03.2022 19:12

На самом деле это было из-за того, что пользователь не был аутентифицирован, теперь я получаю System.InvalidCastException: «Невозможно преобразовать объект типа «System.Security.Principal.GenericIdentity» в тип «System.Security.Principal.WindowsIdentity» :-(

James 29.03.2022 19:17

Используете ли вы проверку подлинности Windows? Или вы использовали аутентификацию с помощью форм?

Gabriel Luci 29.03.2022 19:22

Использование активного каталога для аутентификации, таким образом, помещая корпоративную учетную запись Windows в логин для веб-сайта.

James 29.03.2022 19:26

Приступил к работе!!! Но немного изменил ваш код var winIdentity = System.Security.Principal.WindowsIdentity.GetCurrent(); var user = new DirectoryEntry($"LDAP://<SID = {winIdentity.User.Value}>");

James 29.03.2022 19:32
WindowsIdentity.GetCurrent() получит пользователя, под которым запущено приложение, который может отличаться от пользователя, вошедшего на ваш сайт. Вероятно, он работает на вашем компьютере для разработки, потому что он работает под управлением IIS Express, который работает с вашими учетными данными. Но при развертывании на сервере WindowsIdentity.GetCurrent() предоставит вам учетные данные пула приложений IIS, что бесполезно.
Gabriel Luci 29.03.2022 19:53

Похоже, вы используете аутентификацию с помощью форм, где пользователь должен ввести свое имя пользователя и пароль, верно? Мой ответ будет работать только с проверкой подлинности Windows. Поэтому вам придется сделать это по-другому, но это зависит от того, как вы это реализовали. HttpContext.User.Identity.Name дает вам имя пользователя?

Gabriel Luci 29.03.2022 19:55

Действительно, вы правы, мое приложение не удалось после развертывания :-( System.Web.HttpContext.Current.User.Identity.Name у меня работает

James 29.03.2022 20:39

Все еще борюсь, просто чтобы дать вам больше информации, я пытаюсь получить телефон во время единого входа

James 29.03.2022 21:47

Что вы подразумеваете под "единым входом"?

Gabriel Luci 30.03.2022 00:36

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

James 30.03.2022 02:49

Это похоже на проверку подлинности Windows. Вы должны увидеть тег <windowsAuthentication ...> в вашем файле web.config. Итак, вернитесь к моему второму комментарию выше и проверьте, какое значение равно нулю.

Gabriel Luci 30.03.2022 15:47
Ответ принят как подходящий

Похоже, я все усложнил, а решение довольно простое.

    private void SetPhone()
    {
        DirectoryEntry entryDomain = new DirectoryEntry("LDAP://" + domain);
        DirectorySearcher ds = new DirectorySearcher(entryDomain);

        string lastName = Context.User.Identity.Name.Split(' ')[Context.User.Identity.Name.Split(' ').Length - 1];

        ds.Filter = "(sn = " + lastName + ")";
        SearchResult sr = ds.FindOne();

        string telephoneNumber = sr.Properties["telephoneNumber"][0].ToString();
        telephoneNumber = telephoneNumber.Insert(0, "(").Insert(4, ")").Insert(5, " ").Insert(9, "-");
        Session["UserPhone"] = String.Format("{0:(###) ###-####}", telephoneNumber); ;
    }

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