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 = "测试认证用户密码";
  • 相关阅读:
    多节点通过PPP连接,节点/用户/客户机之间互相访问ping
    nginx的autoindex,目录浏览,配置和美化,美观的xslt_stylesheet
    用EM4305/T5557模拟EM4100的ID卡,原理解释
    CentOS7用hostapd做radius服务器为WiFi提供802.1X企业认证
    用openssl为WEB服务器生成证书(自签名CA证书,服务器证书)
    去freessl.org申请免费ssl服务器证书
    用openssl为EAP-TLS生成证书(CA证书,服务器证书,用户证书)
    自建简单又实用的动态域名管理系统
    SpringBoot自动装配原理
    Mysql中的范式
  • 原文地址:https://www.cnblogs.com/rangeon/p/7132481.html
Copyright © 2011-2022 走看看