65.9K
CodeProject 正在变化。 阅读更多。
Home

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

2020年7月15日

CPOL

1分钟阅读

viewsIcon

39351

downloadIcon

765

在 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

参考文献

限制

  • LDAP 路径可能不像我的那样简单,请根据需要进行修改。
  • 代码可能对未经测试的输入抛出错误,如果出现问题请告诉我

历史

  • 2020年7月15日:初始版本
© . All rights reserved.