简体   繁体   English

.NET C#中的LDAP连接

[英]Ldap connection in .net C#

I have an application where I can send emails. 我有一个可以发送电子邮件的应用程序。 Now am asked to use ldap to authenticate the user email. 现在,要求使用ldap对用户电子邮件进行身份验证。 Am very new to this concept. 这个概念很新。 I have been given a ldap server link. 我得到了一个ldap服务器链接。 No idea how to proceed with that. 不知道该如何进行。 Any article or hits will be greatly helpful. 任何文章或点击都将大有帮助。

Here is the code am trying with 这是我正在尝试的代码

public static UserDetail GetUserDetails(string EmailId, string domainName)
{
    UserDetail userDetail = new UserDetail();

    try
    {
        string filter = string.Format("(&(ObjectClass={0})(sAMAccountName={1}))", "person", EmailId);
        string[] properties = new string[] { "fullname" };

        DirectoryEntry adRoot = new DirectoryEntry("LDAP://" + domainName, null, null, AuthenticationTypes.Secure);
        DirectorySearcher searcher = new DirectorySearcher(adRoot);
        searcher.SearchScope = SearchScope.Subtree;
        searcher.ReferralChasing = ReferralChasingOption.All;
        searcher.PropertiesToLoad.AddRange(properties);
        searcher.Filter = filter;
        SearchResult result = searcher.FindOne();

        DirectoryEntry directoryEntry = result.GetDirectoryEntry();
        string displayName = directoryEntry.Properties["displayName"[0].ToStrin();
        string firstName = directoryEntry.Properties["givenName"][0].ToString();
        string lastName = directoryEntry.Properties["sn"][0].ToString();
        string emailId = directoryEntry.Properties["mail"][0].ToString();

        userDetail.EmailId = emailId;
    }
    catch (Exception)
    {

    }
    return userDetail;
}

I want to achieve it on click of search button. 我想通过单击搜索按钮来实现。 How do I call the method and pass variables. 如何调用方法并传递变量。

If you're on .NET 3.5 or newer, you can use a PrincipalSearcher and a "query-by-example" principal to do your searching: 如果您使用的是.NET 3.5或更高版本,则可以使用PrincipalSearcher和“按示例查询”主体进行搜索:

// create your domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);

// define a "query-by-example" principal - here, we search for a UserPrincipal 
// and with the e-mail of "bruce@example.com"
UserPrincipal qbeUser = new UserPrincipal(ctx);
qbeUser.EmailAddress = "bruce@example.com";

// create your principal searcher passing in the QBE principal    
PrincipalSearcher srch = new PrincipalSearcher(qbeUser);

// try to find that user
UserPrincipal found = srch.FindOne() as UserPrincipal;

if(found != null)
{
    // do whatever here - "found" is the user that matched the e-mail given
}
else
{
    // there wasn't any user with that e-mail address in your AD
}

If you haven't already - absolutely read the MSDN article Managing Directory Security Principals in the .NET Framework 3.5 which shows nicely how to make the best use of the new features in System.DirectoryServices.AccountManagement . 如果您还没有-绝对请阅读MSDN文章.NET Framework 3.5中的管理目录安全性主体”,它很好地展示了如何充分利用System.DirectoryServices.AccountManagement中的新功能。 Or see the MSDN documentation on the System.DirectoryServices.AccountManagement namespace. 或参阅System.DirectoryServices.AccountManagement命名空间MSDN文档

Of course, depending on your need, you might want to specify other properties on that "query-by-example" user principal you create: 当然,根据您的需要,您可能希望在创建的“按示例查询”用户主体上指定其他属性:

  • DisplayName (typically: first name + space + last name) DisplayName (通常:名字+空格+姓氏)
  • SAM Account Name - your Windows/AD account name SAM Account Name -您的Windows / AD帐户名
  • User Principal Name - your "username@yourcompany.com" style name User Principal Name -您的“ username@yourcompany.com”样式名称

You can specify any of the properties on the UserPrincipal and use those as "query-by-example" for your PrincipalSearcher . 您可以在UserPrincipal上指定任何属性,并将它们用作PrincipalSearcher “按示例查询”。

Given the input of emailAddress (type string) this code will search the LDAP directory for a user with a matching email address and return some information on the user: 给定emailAddress(类型字符串)的输入,此代码将在LDAP目录中搜索具有匹配电子邮件地址的用户,并返回有关该用户的一些信息:

string fullName = string.Empty;
            string givenName = string.Empty;
            string distinguishedName = string.Empty;
            string sAMAccountName = string.Empty;
            using (var context = new PrincipalContext(ContextType.Domain, "DOMAIN"))
            {
                using (var searcher = new PrincipalSearcher(new UserPrincipal(context)))
                {
                    foreach (Principal result in searcher.FindAll())
                    {
                        var de = result.GetUnderlyingObject() as DirectoryEntry;

                        if (de.Properties["cn"].Value.ToString().Contains(" "))
                        {

                            //var userEntry = new DirectoryUser(de.Properties["sAMAccountName"].Value.ToString());
                            var currentUserEmail = de.Properties["mail"].Value.ToString().ToLower();
                            if (currentUserEmail == emailAddress)
                            {

                                if (de.Properties["cn"].Value != null)
                                    fullName = de.Properties["cn"].Value.ToString();
                                if (de.Properties["givenName"].Value != null)
                                   givenName = de.Properties["givenName"].Value.ToString();
                                if (de.Properties["distinguishedName"].Value != null)
                                    distinguishedName =de.Properties["distinguishedName"].Value.ToString();
                                if (de.Properties["sAMAccountName"].Value != null)
                                    sAMAccountName = de.Properties["sAMAccountName"].Value.ToString();


                            }
                        }
                    }
                }
            }

It requires a reference to : 它需要参考:

System.DirectoryServices;
System.DirectoryServices.AccountManagement;

One caveat I would like to mention is, directory look up routines can be quite slow. 我要提到的一个警告是,目录查找例程可能非常慢。 If you have 100,000 users on your domain, this process will take a while to run. 如果您的域上有100,000个用户,则此过程将需要一段时间才能运行。 WHat I tend to do, is dump the output of a directory search to a database table on a regular basis, and perform any lookups on that table. 我倾向于这样做,是将目录搜索的输出定期转储到数据库表中,并在该表上执行任何查找。 The frequency of the database dumps will of course depend on your business logic. 数据库转储的频率当然取决于您的业务逻辑。 Sometimes I simply truncate the table before performing a new dump, and in other circumstances, I dump to a 'staging' table, and only apply 'delta' updates to the active directoy record table. 有时,我只是在执行新转储之前就截断了表,而在其他情况下,我转储到了“暂存”表,并且仅对活动的Directoy记录表应用了“增量”更新。

  • Connect to the directory server, using SSL if possible. 如果可能,使用SSL连接到目录服务器。 Promoting a non-secure connection to a secure connection with the StartTLS extended operation is also possible. 也可以通过StartTLS扩展操作将非安全连接提升为安全连接。
  • Transmit a SEARCH request to the server that contains the base DN from which the client wishes the search to begin, the scope of the search (base, one-level, or sub-tree), a filter using the information the LDAP client knows that will narrow the search results to the desired user, and the attribute 1.1 . 将SEARCH请求发送到服务器,该请求包含客户端希望从其开始搜索的基本DN,搜索范围(基本,单级或子树),使用LDAP客户端知道的信息的过滤器会将搜索结果缩小到所需的用户,并将属性1.1缩小。
  • The server will respond with the a SEARCH response containing the number of entries that matched the search request parameters and the distinguished names of each entry that matched. 服务器将以SEARCH响应进行响应,该SEARCH响应包含与搜索请求参数匹配的条目数量以及与之匹配的每个条目的专有名称。
  • Transmit a BIND request to the directory server over the secure connection. 通过安全连接将BIND请求发送到目录服务器。 The BIND request contains a distinguished name and the credentials for the distinguished name BIND请求包含一个专有名称和专有名称的凭证
  • The directory server will verify the credentials and return a BIND response with an integer result code indicating whether the credentials matched those stored in the server database 目录服务器将验证凭据,并返回带有整数结果代码的BIND响应,指示代码是否与服务器数据库中存储的凭据匹配

see also 也可以看看

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM