Как я могу подтвердить имя пользователя и пароль в Active Directory? Я просто хочу проверить правильность имени пользователя и пароля.Подтвердить имя пользователя и пароль в Active Directory?
ответ
Вероятно, самым простым способом является PInvoke LogonUser Win32 API.e.g.
MSDN Ссылка здесь ...
Определенно нужно использовать тип входа
LOGON32_LOGON_NETWORK (3)
Это создает легкий токен - идеально подходит для проверок AuthN. (Другие типы могут быть использованы для создания интерактивных сессий и т.д.)
Попробуйте этот код (Примечание: Сообщил, чтобы не работать на Windows Server 2000)
#region NTLogonUser
#region Direct OS LogonUser Code
[DllImport("advapi32.dll")]
private static extern bool LogonUser(String lpszUsername,
String lpszDomain, String lpszPassword, int dwLogonType,
int dwLogonProvider, out int phToken);
[DllImport("Kernel32.dll")]
private static extern int GetLastError();
public static bool LogOnXP(String sDomain, String sUser, String sPassword)
{
int token1, ret;
int attmpts = 0;
bool LoggedOn = false;
while (!LoggedOn && attmpts < 2)
{
LoggedOn= LogonUser(sUser, sDomain, sPassword, 3, 0, out token1);
if (LoggedOn) return (true);
else
{
switch (ret = GetLastError())
{
case (126): ;
if (attmpts++ > 2)
throw new LogonException(
"Specified module could not be found. error code: " +
ret.ToString());
break;
case (1314):
throw new LogonException(
"Specified module could not be found. error code: " +
ret.ToString());
case (1326):
// edited out based on comment
// throw new LogonException(
// "Unknown user name or bad password.");
return false;
default:
throw new LogonException(
"Unexpected Logon Failure. Contact Administrator");
}
}
}
return(false);
}
#endregion Direct Logon Code
#endregion NTLogonUser
кроме вам необходимо создать свой собственный исключение для «LogonException»
Не используйте обработку исключений для возврата информации из метода. «Неизвестное имя пользователя или неверный пароль» не является исключительным, это стандартное поведение для LogonUser. Просто верните false. – Treb 2008-11-14 16:20:33
Да ... это был порт из старой библиотеки VB6 ... написан 2003 или около того ... (когда .Net впервые вышел) – 2008-11-17 15:18:07
Если в Windows 2000 этот код не будет работать (http: // support. microsoft.com/kb/180548) – 2008-12-01 14:58:56
Мы делаем это на нашем интранете
Вы должны использовать 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();
}
}
}
Этот код не нужно запускать как пользователь AD? – bzlm 2008-11-14 16:13:40
Что вы вкладываете в «путь»? Имя домена? Имя сервера? Путь LDAP к домену? Путь LDAP к серверу? – 2008-12-01 15:00:59
Answer1: Нет, мы запускаем его как веб-службу, чтобы его можно было вызывать из нескольких мест в основном веб-приложении. Ответ2: Путь содержит информацию LDAP ... LDAP: // DC = domainname1, DC = domainname2, DC = com – 2008-12-01 18:21:30
очень простое решение с использованием 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 требуется для обнаружения плохой пользователя/пароль
полный. 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, от клиента за пределами домена!
К сожалению, нет простого способа проверить учетные данные пользователей в AD.
С каждым способом, представленным до сих пор, вы можете получить ложноотрицательный: кредитки пользователя будет действительным, однако AD будет возвращать ложь при определенных обстоятельствах:
- Пользователь требуется изменить пароль при следующем входе в систему ,
- Срок действия истек истек.
ActiveDirectory не позволит использовать LDAP для определения того, является ли пароль недопустимым из-за того, что пользователь должен сменить пароль или срок его пароля истек.
Чтобы определить изменение пароля или пароля истек, вы можете вызвать Win32: LogonUser(), и проверьте окна код ошибки для следующих 2 констант:
- ERROR_PASSWORD_MUST_CHANGE = 1907
- ERROR_PASSWORD_EXPIRED = 1330
Если вы работаете на .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% C# на вашем конце - что еще вы можете попросить? :-)
Читайте об этом здесь:
- Managing Directory Security Principals in the .NET Framework 3.5
- MSDN docs on System.DirectoryServices.AccountManagement
Update:
Как указано в this other SO question (and its answers), есть проблема с этим вызовом возможно, возвращая True
для старых паролей пользователя. Просто помните об этом поведении и не удивляйтесь, если это произойдет :-) (спасибо @MikeGledhill за указание этого!)
Вы уверены? ??? Я получил исключение PrincipalServerdownException, когда я это пробовал ... – 2009-05-29 04:59:09
Я попробовал: PrincipalContext pc = new PrincipalContext (ContextType.Domain, "yourdomain"); Ваш пробег может отличаться. – 2009-05-29 05:03:02
Если вы застряли с .NET 2.0 и управляемым кодом, вот еще один способ который работает ти локальных и доменных учетных записей:
using System;
using System.Collections.Generic;
using System.Text;
using System.Security;
using System.Diagnostics;
static public bool Validate(string domain, string username, string password)
{
try
{
Process proc = new Process();
proc.StartInfo = new ProcessStartInfo()
{
FileName = "no_matter.xyz",
CreateNoWindow = true,
WindowStyle = ProcessWindowStyle.Hidden,
WorkingDirectory = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData),
UseShellExecute = false,
RedirectStandardError = true,
RedirectStandardOutput = true,
RedirectStandardInput = true,
LoadUserProfile = true,
Domain = String.IsNullOrEmpty(domain) ? "" : domain,
UserName = username,
Password = Credentials.ToSecureString(password)
};
proc.Start();
proc.WaitForExit();
}
catch (System.ComponentModel.Win32Exception ex)
{
switch (ex.NativeErrorCode)
{
case 1326: return false;
case 2: return true;
default: throw ex;
}
}
catch (Exception ex)
{
throw ex;
}
return false;
}
Еще один вызов .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
}
}
Несколько решений, представленные здесь не обладают способностью различать неверном пользователя/пароль, и пароль, который необходимо изменить. Это может быть сделано следующим образом:
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 ошибка, 52е данных, 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)
My Simple Функция
private bool IsValidActiveDirectoryUser(string activeDirectoryServerDomain, string username, string password)
{
try
{
DirectoryEntry de = new DirectoryEntry("LDAP://" + activeDirectoryServerDomain, username + "@" + activeDirectoryServerDomain, password, AuthenticationTypes.Secure);
DirectorySearcher ds = new DirectorySearcher(de);
ds.FindOne();
return true;
}
catch //(Exception ex)
{
return false;
}
}
аутентификация Windows, может потерпеть неудачу по различным причинам: неправильное имя пользователя или пароль, заблокированная учетной запись , истекший пароль и т. д. Для того, чтобы различать эти ошибки, вызовите функцию LogonUser API через P/Invoke и проверьте код ошибки, если функция возвращает false
:
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
public static class Win32Authentication
{
private class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid
{
private SafeTokenHandle() // called by P/Invoke
: base(true)
{
}
protected override bool ReleaseHandle()
{
return CloseHandle(this.handle);
}
}
private enum LogonType : uint
{
Network = 3, // LOGON32_LOGON_NETWORK
}
private enum LogonProvider : uint
{
WinNT50 = 3, // LOGON32_PROVIDER_WINNT50
}
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool CloseHandle(IntPtr handle);
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool LogonUser(
string userName, string domain, string password,
LogonType logonType, LogonProvider logonProvider,
out SafeTokenHandle token);
public static void AuthenticateUser(string userName, string password)
{
string domain = null;
string[] parts = userName.Split('\\');
if (parts.Length == 2)
{
domain = parts[0];
userName = parts[1];
}
SafeTokenHandle token;
if (LogonUser(userName, domain, password, LogonType.Network, LogonProvider.WinNT50, out token))
token.Dispose();
else
throw new Win32Exception(); // calls Marshal.GetLastWin32Error()
}
}
Пример использования:
try
{
Win32Authentication.AuthenticateUser("EXAMPLE\\user", "[email protected]");
// Or: Win32Authentication.AuthenticateUser("[email protected]", "[email protected]");
}
catch (Win32Exception ex)
{
switch (ex.NativeErrorCode)
{
case 1326: // ERROR_LOGON_FAILURE (incorrect user name or password)
// ...
case 1327: // ERROR_ACCOUNT_RESTRICTION
// ...
case 1330: // ERROR_PASSWORD_EXPIRED
// ...
case 1331: // ERROR_ACCOUNT_DISABLED
// ...
case 1907: // ERROR_PASSWORD_MUST_CHANGE
// ...
case 1909: // ERROR_ACCOUNT_LOCKED_OUT
// ...
default: // Other
break;
}
}
Примечание: LogonUser требует доверительных отношений с доменом, на который вы проверяете.
- 1. Подтвердить пользователя в Azure Active Directory; Не использовать SSO, но используя имя пользователя и пароль
- 2. Подтвердить пользователей удаленной Active Directory в C#
- 3. Проверка пользователя Active Directory
- 4. Обновление Active Directory без жесткого кодирования имя пользователя/пароль
- 5. Подтвердить имя пользователя и пароль для исключения AD.
- 6. Получить имя пользователя Active Directory Active Directory от Django
- 7. Не удалось подтвердить имя пользователя и пароль
- 8. Старое имя пользователя в Active Directory
- 9. Поиск пользователя в Active Directory Полное имя
- 10. Имя пользователя Active Directory в проекте AngularJS
- 11. Регулярное выражение для Active Directory Пароль
- 12. Подтвердить имя пользователя NT + пароль в ASP.NET
- 13. Как подтвердить пароль пользователя и имя пользователя в Vb.net?
- 14. Получить имя ПК с помощью Active Directory
- 15. C# Active Directory Client Имя пользователя
- 16. Пароль смены Active Directory и деактивированный статус
- 17. C# Active Directory: получить доменное имя пользователя?
- 18. Получить имя пользователя из Active Directory
- 19. Получить Имя пользователя из Active Directory
- 20. как установить lockoutTime и пароль пользователя Active Directory
- 21. Подтвердить имя пользователя и пароль без аутентификации пользователя
- 22. Изменение пароля пользователя Active Directory
- 23. Добавить пользователя в Active Directory
- 24. Хранение менеджера Пароль Active Directory
- 25. Active Directory - Роли пользователя
- 26. Аутентифицировать пользователя в Active Directory в ASP.Net
- 27. Active Directory Создание пользователя
- 28. Атрибуты пользователя Active Directory
- 29. Подтвердить пароль и имя пользователя в android с помощью httppost
- 30. Подтвердить имя пользователя и пароль в Microsoft VIsual Studio
Как указывает @Alan, API LogonUser имеет много полезных черт помимо вызова System.DirectoryServices. – stephbu 2008-12-01 17:48:17
@cciotti: Нет, это неправильно. ЛУЧШИЙ способ правильно аутентифицировать кого-то - использовать LogonUserAPI как @stephbu write. Все другие методы, описанные в этом сообщении, НЕ РАБОТАЮТ на 100%. Просто заметьте, однако, я считаю, что вы должны быть присоединены к домену, чтобы вызвать LogonUser. – Alan 2009-04-20 18:28:04
@Alan, чтобы сгенерировать учетные данные, вы должны иметь возможность подключиться к домену, передав действительную учетную запись домена. Однако я уверен, что ваша машина не обязательно должна быть членом домена. – stephbu 2009-04-21 02:15:30