最近由于项目需要研究了一下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之后才能正常工作了。

     //----------------------------------------------------------------------------------------------
// DirectoryEntry 方案, 需要引用 System.DirectoryServices
//----------------------------------------------------------------------------------------------
var ldapPath = "LDAP://" + host + "/" + baseDN; // LDAP必须要大写,好像是.NET的特色
DirectoryEntry de = new DirectoryEntry(ldapPath, adminName, adminPass, AuthenticationTypes.FastBind);
DirectorySearcher searcher = new DirectorySearcher(de);
searcher.Filter = "(uid=" + testUser + ")";
searcher.SearchScope = SearchScope.Subtree;
searcher.PropertiesToLoad.Add("uid");
searcher.PropertiesToLoad.Add("cn"); var result = searcher.FindOne(); // 输出几个查询的属性值
foreach (string n in result.Properties.PropertyNames)
{
Console.WriteLine("{0}: {1}", n, result.Properties[n][].ToString());
} try
{
int pos = result.Path.LastIndexOf('/');
string uid = result.Path.Remove(, pos + ); // 二次连接,使用需要认证的用户密码尝试连接
DirectoryEntry deUser = new DirectoryEntry(ldapPath, uid, testPass, AuthenticationTypes.FastBind);
var connected = deUser.NativeObject; Console.WriteLine("### 认证成功!");
}
catch
{
Console.WriteLine("认证失败~~~");
}

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

     //------------------------------------------------------------------------------------------
// LdapConnection 方案, 需要引用 System.DirectoryServices.Protocols
//------------------------------------------------------------------------------------------
var identifier = new LdapDirectoryIdentifier(host);
var conn = new LdapConnection(identifier, new NetworkCredential
{
UserName = adminName,
Password = adminPass
});
conn.AuthType = AuthType.Basic;
conn.Bind(); var request = new SearchRequest(baseDN, "(uid=" + testUser + ")", SearchScope.Subtree, "otherPassword");
SearchResponse response = conn.SendRequest(request) as SearchResponse;
if (response.Entries != null && response.Entries.Count > )
{
try
{
var connUser = new LdapConnection(identifier, new NetworkCredential
{
UserName = response.Entries[].DistinguishedName,
Password = testPass
});
connUser.AuthType = AuthType.Basic;
connUser.Bind(); Console.WriteLine("### 认证成功!");
}
catch
{
Console.WriteLine("认证失败~~~ error password");
}
}
else
{
Console.WriteLine("认证失败~~~ no user");
}

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

     var host = "xxx.xxx.xxx.xxx:389";
var baseDN = "dc=xxx,dc=xxx,dc=com";
var adminName = "uid=管理账号,ou=管理组," + baseDN;
var adminPass = "管理密码";
var testUser = "测试认证用户账号";
var testPass = "测试认证用户密码";

最新文章

  1. C#动态调用WCF接口,两种方式任你选。
  2. JS简介
  3. 一款APP从设计稿到切图过程全方位揭秘 Mark
  4. Date简介
  5. VHDL程序的库
  6. ikely()与unlikely() 都等同于if, 此处只是做编译优化
  7. XMLHttpRequest基础知识
  8. OpenSuSE查看指定软件包是否安装(OpenSuSE使用RPM作为默认的软件包维护管理工具)
  9. jquery ajax调用
  10. hdu1021
  11. LeetCode OJ 73. Set Matrix Zeroes
  12. 每天一道Java题[3]
  13. Python之日志处理(logging模块)
  14. idea的debug调试快捷键
  15. 第七章:Python基础のXML操作和面向对象(一)
  16. 详解PHP中的过滤器(Filter)
  17. java_lambda表达式
  18. python 中面向对象的概念
  19. web 前端知识体系 网站资源分析
  20. 自定义标签tld的使用

热门文章

  1. simotion ST编程,变量和程序的模块化
  2. ring0 SSDTHook 实现x64/x86
  3. nodejs一个函数实现消息队列中间件
  4. MSD_radix_sort
  5. java连接ssh执行shell脚本
  6. 转:SSM框架——详细整合教程(Spring+SpringMVC+MyBatis)
  7. Nginx启用Gzip压缩js无效的原因
  8. 2017.9.20 HTML学习总结----下拉列表标签
  9. mysql中locate和substring函数使用
  10. 第29章 电容触摸屏—触摸画板—零死角玩转STM32-F429系列