rusqhyazeubebgcahrcsdanlenetfifrglkadeelhuisgaitkkkylvltmknoplptrosrskslessvtrukuz

Проверить имя пользователя и пароль в Active Directory

Больше
3 мес. 1 нед. назад #234 от О.Коровяков
Как я могу проверить имя пользователя и пароль для Active Directory? Я просто хочу проверить правильность имени пользователя и пароля.

Если вы работаете с .NET 3.5 или новее, вы можете использовать пространство имен System.DirectoryServices.AccountManagement и легко проверить свои учетные данные:
// create a "principal context" - e.g. your domain (could be machine, too)
using(PrincipalContext pc = new PrincipalContext(ContextType.Domain, "YOURDOMAIN"))
{
    // validate the credentials
    bool isValid = pc.ValidateCredentials("myuser", "mypassword");
}

Это простой, надежный, он на 100% управляемый код на вашем конце - что еще вы можете спросить?: -)

Подробнее читайте здесь:

Управление принципами безопасности каталога в .NET Framework 3.5 (EN)
Документы MSDN в System.DirectoryServices.AccountManagement (EN)

Update:

Существует проблема с этим вызовом, возможно, возвращая True для старых паролей пользователя. Просто помните об этом поведении и не удивляйтесь, если это произойдет:-)

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Больше
3 мес. 1 нед. назад #235 от О.Коровяков
Мы делаем это в нашей Интранет

Вы должны использовать System.DirectoryServices;

Вот строки кода
using (DirectoryEntry adsEntry = new DirectoryEntry(path, strAccountId, strPassword))
{
    using (DirectorySearcher adsSearcher = new DirectorySearcher(adsEntry))
    {
        //adsSearcher.Filter = "(&(objectClass=user)(objectCategory=person))";
        adsSearcher.Filter = "(sAMAccountName=" + strAccountId + ")";
 
        try
        {
            SearchResult adsSearchResult = adsSearcher.FindOne();
            bSucceeded = true;
 
            strAuthenticatedBy = "Active Directory";
            strError = "User has been authenticated by Active Directory.";
        }
        catch (Exception ex)
        {
            // Failed to authenticate. Most likely it is caused by unknown user
            // id or bad strPassword.
            strError = ex.Message;
        }
        finally
        {
            adsEntry.Close();
        }
    }
}

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Больше
3 мес. 1 нед. назад - 3 мес. 1 нед. назад #236 от О.Коровяков
В нескольких представленных здесь решениях нет возможности различать неправильный пользователь/пароль и пароль, который необходимо изменить. Это можно сделать следующим образом:
using System;
using System.DirectoryServices.Protocols;
using System.Net;
 
namespace ProtocolTest
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                LdapConnection connection = new LdapConnection("ldap.fabrikam.com");
                NetworkCredential credential = new NetworkCredential("user", "password");
                connection.Credential = credential;
                connection.Bind();
                Console.WriteLine("logged in");
            }
            catch (LdapException lexc)
            {
                String error = lexc.ServerErrorMessage;
                Console.WriteLine(lexc);
            }
            catch (Exception exc)
            {
                Console.WriteLine(exc);
            }
        }
    }
}

Если пароль пользователя неверен или пользователь не существует, ошибка будет содержать

"8009030C: LdapErr: DSID-0C0904DC, комментарий: Ошибка AcceptSecurityContext, данные 52e, v1db1",

если пароль пользователя нужно изменить, он будет содержать

"8009030C: LdapErr: DSID-0C0904DC, комментарий: Ошибка AcceptSecurityContext, данные 773, v1db1"

Значение данных lexc.ServerErrorMessage представляет собой шестнадцатеричное представление кода ошибки Win32. Это те же коды ошибок, которые были бы возвращены путем вызова вызова Win32 LogonUser API. В приведенном ниже списке представлены общие значения с шестнадцатеричным и десятичным значениями:
525​ user not found ​(1317)
52e​ invalid credentials ​(1326)
530​ not permitted to logon at this time​ (1328)
531​ not permitted to logon at this workstation​ (1329)
532​ password expired ​(1330)
533​ account disabled ​(1331) 
701​ account expired ​(1793)
773​ user must reset password (1907)
775​ user account locked (1909)

Не забудьте добавить некоторые ссылки на проект: System.DirectoryServices и System.DirectoryServices.Protocols
Последнее редактирование: 3 мес. 1 нед. назад пользователем О.Коровяков.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Больше
3 мес. 1 нед. назад - 3 мес. 1 нед. назад #237 от О.Коровяков
очень простое решение с использованием DirectoryServices:
using System.DirectoryServices;
 
//srvr = ldap server, e.g. LDAP://domain.com
//usr = user name
//pwd = user password
public bool IsAuthenticated(string srvr, string usr, string pwd)
{
    bool authenticated = false;
 
    try
    {
        DirectoryEntry entry = new DirectoryEntry(srvr, usr, pwd);
        object nativeObject = entry.NativeObject;
        authenticated = true;
    }
    catch (DirectoryServicesCOMException cex)
    {
        //not authenticated; reason why is in cex
    }
    catch (Exception ex)
    {
        //not authenticated due to some other exception [this is optional]
    }
 
    return authenticated;
}

для обнаружения плохих пользователей/паролей требуется доступ к NativeObject



Этот код плох, потому что он также выполняет проверку авторизации (проверьте, разрешено ли пользователю читать информацию активного каталога). Имя пользователя и пароль могут быть действительными, но пользователю не разрешено читать информацию - и получить исключение. Другими словами, вы можете иметь действительное имя пользователя и пароль, но все равно получите исключение.

На самом деле я нахожусь в процессе запроса нативный эквивалент PrincipleContext - который существует только в .NET 3.5. Но если вы используете .NET 3.5 или новее, вы должны использовать PrincipleContext

К сожалению, нет простого способа проверить учетные данные пользователей в AD.

С каждым представленным до сих пор способом вы можете получить ложно-отрицательный: пользовательские creds будут действительны, однако AD при возврате false будет возвращать false:

Пользователь должен сменить пароль при следующем входе в систему.
Срок действия пароля пользователя истек.
ActiveDirectory не позволит вам использовать LDAP, чтобы определить, недействителен ли пароль из-за того, что пользователь должен сменить пароль или срок их пароля истек.

Чтобы определить изменение пароля или срок действия пароля истек, вы можете вызвать Win32: LogonUser() и проверить код ошибки Windows для следующих 2 констант:

ERROR_PASSWORD_MUST_CHANGE = 1907
ERROR_PASSWORD_EXPIRED = 1330


Вероятно, самым простым способом является PInvoke LogonUser Win32 API.e.g.

www.pinvoke.net/default.aspx/advapi32/LogonUser.html

Ссылка MSDN здесь...

msdn.microsoft.com/en-us/library/aa378184.aspx

Определенно хотите использовать тип входа
LOGON32_LOGON_NETWORK (3)

Это создает только легкий токен - идеально подходит для проверок AuthN. (другие типы могут использоваться для создания интерактивных сеансов и т.д.)

Лучший способ правильно аутентифицировать кого-либо - это использовать LogonUserAPI для записи @stephbu. Все остальные методы, описанные в этом посте, не будут работать на 100%. Однако, просто заметка, я считаю, что вы должны быть присоединены к домену, чтобы вызвать LogonUser.
Последнее редактирование: 3 мес. 1 нед. назад пользователем О.Коровяков.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Больше
3 мес. 1 нед. назад #238 от О.Коровяков
Полное решение .Net - использовать классы из пространства имен System.DirectoryServices. Они позволяют напрямую запрашивать сервер AD. Вот небольшой пример, который бы сделал это:
using (DirectoryEntry entry = new DirectoryEntry())
{
    entry.Username = "here goes the username you want to validate";
    entry.Password = "here goes the password";
 
    DirectorySearcher searcher = new DirectorySearcher(entry);
 
    searcher.Filter = "(objectclass=user)";
 
    try
    {
        searcher.FindOne();
    }
    catch (COMException ex)
    {
        if (ex.ErrorCode == -2147023570)
        {
            // Login or password is incorrect
        }
    }
}
 
// FindOne() didn't throw, the credentials are correct

Этот код напрямую подключается к серверу AD, используя предоставленные учетные данные. Если учетные данные недействительны, искатель .FindOne() выдаст исключение. ErrorCode соответствует ошибке COM недопустимого имени пользователя/пароля.

Вам не нужно запускать код как пользователь AD. Фактически, я успешно использую его для запроса информации на сервере AD, от клиента за пределами домена!

----
как насчет типов аутентификации? Я думаю, что вы забыли это в коде выше. :-) по умолчанию DirectoryEntry.AuthenticationType установлен на Защищенное право? этот код не будет работать на незащищенных LDAP (возможно, Anonymous или None). я прав с этим? – jerbersoft 12 нояб. 2010, в 03:47

Недостатком запроса к серверу AD является то, что у вас есть разрешение на запрос к серверу AD. Ваши учетные данные могут быть действительными, но если у вас нет разрешения на запрос AD, вы получите ошибку. Вот почему был создан так называемый Fast Bind ; вы проверяете учетные данные, не давая пользователю возможности что-либо делать. – Ian Boyd 19 март 2015, в 14:16

Разве это не позволит кому-либо пройти в случае, если исключение COMEx выдается по какой-либо другой причине до проверки учетных данных? – Stefan Paul Noack 05 янв. 2017, в 17:09

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Больше
3 мес. 1 нед. назад #239 от О.Коровяков
Еще один вызов .NET для быстрой аутентификации учетных данных LDAP:
using System.DirectoryServices;
 
using(var DE = new DirectoryEntry(path, username, password)
{
    try
    {
        DE.RefreshCache(); // This will force credentials validation
    }
    catch (COMException ex)
    {
        // Validation failed - handle how you want
    }
}

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Подпишитесь на наши новости...

Если вам интересны материалы опубликованных на Нашем сайте, Вы можете подписаться на рассылку информационных бюллетеней о новых публикациях ... Просто введите адрес электронной почты на какую Вы хотите получать Новости и нажмите кнопку "Подписаться"

Контакт Инфо

Ok-Wood.
08304 ул.Салютная,c.Гнедын,
Киевская обл, Украина
  • Тел: +39 067 492 41 24
    Tel: +38 095 095 88 60
  • Email: info@ok-wood.com.ua
  • Web: ok-wood.com.ua

Весь процесс строительства описан на страницах сайта, но более подробно о технологии, методах строительства, и всех деталях - Вы можете узнать в книге.