C#: 从 LDAP 验证用户名和密码





4.00/5 (3投票s)
在 ASP.NET 和 ASP.NET Core 中从 LDAP 服务器验证用户名和密码的过程
ASP.NET
我们需要在项目中添加 System.DirectoryServices
DLL 引用。在 packages.config 文件中,我们可以添加以下包,或者使用 NuGet 进行安装。
<packages>
<package id="System.DirectoryServices" version="4.7.0" targetFramework="net461" />
</packages>
这是管理器类,Validate(string userId, string password)
方法将从 LDAP 服务器验证信息。
/*
* Links:
* https://nuget.net.cn/packages/System.DirectoryServices/
*/
using System.DirectoryServices;
namespace DotNet
{
/// <summary>
/// Ldap related contracts
/// </summary>
public interface ILdapValidator
{
/// <summary>
/// Check if user in Ldap
/// </summary>
/// <param name="userId">Ldap user name without domain name</param>
/// <param name="password">Ldap passsword</param>
bool Validate(string userId, string password);
}
/// <summary>
/// Ldap related tasks manager
/// </summary>
public class LdapManager : ILdapValidator
{
/// <summary>
/// Domain name from config file
/// </summary>
public readonly string DomainName;
/// <summary>
/// Port name form config file, default 389
/// </summary>
public readonly int PortNumber;
public LdapManager(string domainName, int port = 389)
{
DomainName = domainName;
PortNumber = port;
}
/// <summary>
/// Check if user in Ldap
/// </summary>
/// <param name="userId">Ldap user name without domain name</param>
/// <param name="password">Ldap passsword</param>
public bool Validate(string userId, string password)
{
try
{
string path = LdapPath();
string username = UserFullId(userId);
DirectoryEntry de = new DirectoryEntry
(path, username, password, AuthenticationTypes.Secure);
DirectorySearcher ds = new DirectorySearcher(de);
ds.FindOne();
return true;
}
catch (DirectoryServicesCOMException ex)
{
return false;
}
}
/// <summary>
/// User full id
/// </summary>
/// <param name="userId">User name</param>
/// <returns>userName@domain</returns>
public string UserFullId(string userId)
{
string value = string.Format(@"{0}@{1}", userId, DomainName);
return value;
}
/// <summary>
/// Get Ldap path from domain and port
/// </summary>
/// <returns></returns>
public string LdapPath()
{
string value = string.Format(@"LDAP://{0}:{1}", DomainName, PortNumber);
return value;
}
}
}
这里,我们使用 LDAP 管理器类来验证用户名和密码
string domain = "LdapdomainNameOrIp.com";
int port = 389;
string user = "user.name";
string password = "password@123";
bool isValied = new LdapManager(domain, port).Validate(user, password);
ASP.NET Core
我们需要在项目中添加 Novell.Directory.Ldap
DLL 引用。在 .csproj 文件中,我们可以添加以下包,或者从 NuGet 安装。
<ItemGroup>
<PackageReference Include="Novell.Directory.Ldap.NETStandard" Version="2.3.8" />
</ItemGroup>
这是管理器类,Validate(string userId, string password)
方法将从 LDAP 服务器验证信息。
/*
* Links:
* https://nuget.net.cn/packages/Novell.Directory.Ldap.NETStandard/2.3.8
*/
using Novell.Directory.Ldap;
using System;
namespace DotNetCore
{
/// <summary>
/// Ldap related contracts
/// </summary>
public interface ILdapValidator
{
/// <summary>
/// Check if user in Ldap
/// </summary>
/// <param name="userId">Ldap user name without domain name</param>
/// <param name="password">Ldap passsword</param>
bool Validate(string userId, string password);
}
/// <summary>
/// Ldap related tasks manager
/// </summary>
public class LdapManager : ILdapValidator
{
/// <summary>
/// Domain name from config file
/// </summary>
public readonly string DomainName;
/// <summary>
/// Port name form config file, default 389
/// </summary>
public readonly int PortNumber;
public LdapManager(string domainName, int port = 389)
{
DomainName = domainName;
PortNumber = port; /*LdapConnection.DEFAULT_PORT*/
}
/// <summary>
/// Check if user in Ldap
/// </summary>
/// <param name="userId">Ldap user name without domain name</param>
/// <param name="password">Ldap passsword</param>
public bool Validate(string userId, string password)
{
try
{
string username = UserFullId(userId);
using (var connection = new LdapConnection { SecureSocketLayer = false })
{
connection.Connect(DomainName, PortNumber);
connection.Bind(username, password);
return connection.Bound;
}
}
catch (LdapException ex)
{
return false;
}
}
/// <summary>
/// User full id
/// </summary>
/// <param name="userId">User name</param>
/// <returns>userName@domain</returns>
public string UserFullId(string userId)
{
string value = string.Format(@"{0}@{1}", userId, DomainName);
return value;
}
}
}
这里,我们使用 LDAP 管理器类来验证用户名和密码
string domain = "LdapdomainNameOrIp.com";
int port = 389;
string user = "user.name";
string password = "password@123";
bool isValied = new LdapManager(domain, port).Validate(user, password);
源代码
这是一个 **Visual Studio 2017** 解决方案,包含控制台项目
- DotNet: .NET Framework 4.6.1
- DotNetCore: .NET Core 2.2
参考文献
- 针对 Active Directory 验证用户名和密码?
- 通过 Active Directory (LDAP) 进行应用程序登录
- ASP.NET Core 2.0 LDAP Active Directory 身份验证
- 在 ASP.NET Core 中使用 DirectoryServices
限制
- LDAP 路径可能不像我的那样简单,请根据需要进行修改。
- 代码可能对未经测试的输入抛出错误,如果出现问题请告诉我
历史
- 2020年7月15日:初始版本