如何对活动目录验证用户名和密码?我只是想检查用户名和密码是否正确。
当前回答
可能最简单的方法是PInvoke LogonUser Win32 api。
http://www.pinvoke.net/default.aspx/advapi32/LogonUser.html
MSDN参考在这里…
http://msdn.microsoft.com/en-us/library/aa378184.aspx
绝对要使用登录类型
LOGON32_LOGON_NETWORK (3)
这只创建了一个轻量级的令牌-完美的认证检查。(其他类型可用于构建交互式会话等)
其他回答
完整的. net解决方案是使用来自系统的类。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服务器。如果凭证无效,则search . findone()将抛出异常。ErrorCode是一个对应于“无效的用户名/密码”COM错误。
您不需要以AD用户的身份运行代码。事实上,我成功地使用它在AD服务器上查询信息,从域外的客户端!
使用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访问来检测坏的用户/密码
我的简单功能
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;
}
}
这里介绍的几个解决方案缺乏区分错误用户/密码和需要更改的密码的能力。这可以通过以下方式来实现:
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);
}
}
}
}
如果用户密码错误,或者用户不存在,error将包含
“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)
我使用这个过程作为DLL登录到我们开发的其他应用程序… (我们目前正在使用OpenEdge Progress)
public static string AzureLogin(string user, string password) {
string status;
try {
new DirectorySearcher(new DirectoryEntry("LDAP://yourdomain.com", user, password) {
AuthenticationType = AuthenticationTypes.Secure,
Username = user,
Password = password
}) {
Filter = "(objectclass=user)"
}.FindOne().Properties["displayname"][0].ToString();
status = $"SUCCESS - User {user} has logged in.";
} catch(System.Exception e) {
status = $"ERROR - While logging in: {e}";
}
return status;
}