zoukankan      html  css  js  c++  java
  • LDAP操作的两种方案

    最近由于项目需要研究了一下LDAP相关知识,感觉对没接触过的人来说还是有点坑的,所以记录下来给大家分享。

    由于是第一次接触,就在网上搜了一些相关的文章,照着示例代码测试,却怎么也连不上LDAP服务器,最后折腾的能连上服务器了,又不能检索用户。

    折腾过程中遇到的主要错误就是:

    • There is no such object on the server.

    • The username or password is incorrect.

    • The server could not be contacted.

    在经历了N小时的煎熬之后,终于找到了第一种解决方案,其实就是参考网上的示例代码,但是示例代码的AuthenticationTypes是None,测试连接的时候总是不能正常连接,LDAP地址只能写host,后面不能跟DN,否则就连不上服务器,而且这种方法连接上服务器也不能检索用户。后来改为AuthenticationTypes.FastBind之后才能正常工作了。

     1     //----------------------------------------------------------------------------------------------
     2     // DirectoryEntry 方案, 需要引用 System.DirectoryServices
     3     //----------------------------------------------------------------------------------------------
     4     var ldapPath = "LDAP://" + host + "/" + baseDN; // LDAP必须要大写,好像是.NET的特色
     5     DirectoryEntry de = new DirectoryEntry(ldapPath, adminName, adminPass, AuthenticationTypes.FastBind);
     6     DirectorySearcher searcher = new DirectorySearcher(de);
     7     searcher.Filter = "(uid=" + testUser + ")";
     8     searcher.SearchScope = SearchScope.Subtree;
     9     searcher.PropertiesToLoad.Add("uid");
    10     searcher.PropertiesToLoad.Add("cn");
    11 
    12     var result = searcher.FindOne();
    13     
    14     // 输出几个查询的属性值
    15     foreach (string n in result.Properties.PropertyNames)
    16     {
    17         Console.WriteLine("{0}: {1}", n, result.Properties[n][0].ToString());
    18     }
    19 
    20     try
    21     {
    22         int pos = result.Path.LastIndexOf('/');
    23         string uid = result.Path.Remove(0, pos + 1);
    24         
    25         // 二次连接,使用需要认证的用户密码尝试连接
    26         DirectoryEntry deUser = new DirectoryEntry(ldapPath, uid, testPass, AuthenticationTypes.FastBind);
    27         var connected = deUser.NativeObject;
    28         
    29         Console.WriteLine("### 认证成功!");
    30     }
    31     catch
    32     {
    33         Console.WriteLine("认证失败~~~");
    34     }

    另外一种方案是我同事找到的,和我上面一种方案几乎在同一时间找到,比较坑,是使用.NET官方类库中的LdapConnection,我一直认为LDAP这么常见的东西一定有官方的解决方案,奈何搜遍了国内外的中文、E文网站,“LDAP C#”、“LDAP .NET”关键字都搜了,就是没有任何人提到关于这个类的片言只字,真无语!难道这玩意就这么冷门吗?难道大家都在用DirectoryEntry吗?不可思议。

     1     //------------------------------------------------------------------------------------------
     2     // LdapConnection 方案, 需要引用 System.DirectoryServices.Protocols
     3     //------------------------------------------------------------------------------------------
     4     var identifier = new LdapDirectoryIdentifier(host);
     5     var conn = new LdapConnection(identifier, new NetworkCredential
     6     {
     7         UserName = adminName,
     8         Password = adminPass
     9     });
    10     conn.AuthType = AuthType.Basic;
    11     conn.Bind();
    12 
    13     var request = new SearchRequest(baseDN, "(uid=" + testUser + ")", SearchScope.Subtree, "otherPassword");
    14     SearchResponse response = conn.SendRequest(request) as SearchResponse;
    15     if (response.Entries != null && response.Entries.Count > 0)
    16     {
    17         try
    18         {
    19             var connUser = new LdapConnection(identifier, new NetworkCredential
    20             {
    21                 UserName = response.Entries[0].DistinguishedName,
    22                 Password = testPass
    23             });
    24             connUser.AuthType = AuthType.Basic;
    25             connUser.Bind();
    26 
    27             Console.WriteLine("### 认证成功!");
    28         }
    29         catch
    30         {
    31             Console.WriteLine("认证失败~~~ error password");
    32         }
    33     }
    34     else
    35     {
    36         Console.WriteLine("认证失败~~~ no user");
    37     }

    测试代码中用到的一些变量声明:

    1     var host = "xxx.xxx.xxx.xxx:389";
    2     var baseDN = "dc=xxx,dc=xxx,dc=com";
    3     var adminName = "uid=管理账号,ou=管理组," + baseDN;
    4     var adminPass = "管理密码";
    5     var testUser = "测试认证用户账号";
    6     var testPass = "测试认证用户密码";
  • 相关阅读:
    boost::asio在VS2008下的编译错误
    Java集合框架——接口
    ACM POJ 3981 字符串替换(简单题)
    ACM HDU 1042 N!(高精度计算阶乘)
    OneTwoThree (Uva)
    ACM POJ 3979 分数加减法(水题)
    ACM HDU 4004 The Frog's Games(2011ACM大连赛区第四题)
    Hexadecimal View (2011ACM亚洲大连赛区现场赛D题)
    ACM HDU 4002 Find the maximum(2011年大连赛区网络赛第二题)
    ACM HDU 4001 To Miss Our Children Time (2011ACM大连赛区网络赛)
  • 原文地址:https://www.cnblogs.com/rangeon/p/7132481.html
Copyright © 2011-2022 走看看