测试环境:VS2008, NET Framework 3.5

公司打算改用LDAP来存储用户名和密码,现在用C#测试下如何能拿到LDAP中的用户名,并检测用户密码是否正确。即输入用户名和密码,可以检验是否是有效的。

首先我们假设LDAP的server IP是127.0.0.1

基本的DN是ou=user,dc=companyname,dc=com

用来登录的管理员name是cn=sysuser,ou=systemaccounts,dc=companyname,dc=com

对应密码是sysuser

上面这些server name,user name和密码都是测试数据,大概如此,真正用时要换成自己公司的有效server,用户才行哦。

一、连接LDAP sever

现在我们来测试下是否能正确连接到LDAP server,代码如下:

  1. DirectoryEntry entry = new DirectoryEntry("LDAP://127.0.0.1/ou=user,dc=companyname,dc=com","cn=sysuser,ou=systemaccounts,dc=companyname,dc=com", "sysuser", AuthenticationTypes.None);
  1.  
  1. try
  1. {
  1. object native = entry.NativeObject;
  1. return true;
  1. }
  1. catch (System.Exception ex)
  1. {
  1. throw new Exception("Error authenticating user." + ex.Message);
  1. }
  1. return false;
  1.  

其中参数AuthenticationTypes.None一定要有,测试的时候没有加这个,结果一直连不到server。

二、列举所有user

现在能连接到LDAP了,我们需要取出公司的所有User,代码如下:

  1. public List<string> EnumerateOU()
  1. {
  1. List<string> lst = new List<string>();
  1. DirectoryEntry entry = new DirectoryEntry("LDAP://127.0.01/ou=user,dc=companyname,dc=com","cn=sysuser,ou=systemaccounts,dc=companyname,dc=com", "sysuser", AuthenticationTypes.None);
  1.  
  1. try
  1. {
  1. object native = entry.NativeObject;
  1. DirectorySearcher searcher = new DirectorySearcher(entry);
  1. searcher.Filter = "(objectClass=account)";
  1. searcher.PropertiesToLoad.Add("cn");
  1. SearchResultCollection ret = searcher.FindAll();
  1. foreach (SearchResult sr in ret)
  1. {
  1. if (sr != null)
  1. {
  1. lst.Add(sr.Properties["cn"][0].ToString());
  1. }
  1. }
  1. }
  1. catch (System.Exception ex)
  1. {
  1. }
  1. return lst;
  1. }

这里声明DirectoryEntry的LDAP server很重要。

LDAP://127.0.0.1/ou=user,….这个是可以取得数据的地址。如果这里ou为其他值,则拿到的就是另外一些数据了。

注意:ou=user…这句是每个公司的规则都不一样,不一定就是ou=user,主要是遵循自己公司的规定。

所有员工应该有个共同的属性,就拿这个共同的属性出来。下面的searcher.Filter也是这样,所有的员工都有个objectClass,它的值可以有多个,但一定都有个值=account,根绝这个规则,我们就可以拿出所有account了。

cn是什么呢?也是LDAP的一个属性,这里cn里面存储的是员工姓名。如果公司的设置不是如此,如何得知哪个node里存储的是什么东东呢?

我们可以将循环改成这样:

  1. foreach (SearchResult sr in ret)
  1. {
  1. foreach (string key in sr.Properties.PropertyNames)
  1. {
  1. foreach (object val in sr.Properties[key])
  1. {
  1. string strTmp = key + " = " + val;
  1. Debug.WriteLine(strTmp);
  1. }
  1. }
  1. }

这样你就可以看到所有属性和它存储的value了。

三、检验某个user name是否存在以及password是否正确。

现在我们来检测一下某个用户名是否存在:

  1. public int IsAuthenticated(string strUserName, string strPwd)
  1. {
  1. DirectoryEntry entry = new DirectoryEntry("LDAP://127.0.01/ou=user,dc=companyname,dc=com","cn=sysuser,ou=systemaccounts,dc=companyname,dc=com", "sysuser", AuthenticationTypes.None);
  1.  
  1. try
  1. {
  1. object native = entry.NativeObject;
  1. DirectorySearcher searcher = new DirectorySearcher(entry);
  1. searcher.Filter = "(cn=" + strUserName + ")";
  1. searcher.PropertiesToLoad.Add("cn");
  1. SearchResult ret = searcher.FindOne();
  1.  
  1. if (sr != null)
  1. return 0; //succeed.
  1. }
  1. }
  1. catch (System.Exception ex)
  1. {
  1. }
  1. return 1; //invalid user
  1. }

这样我们就可以检测到某个用户名是否存在了。这里我们用的Filter是cn=username,实际应用时,要检查自己用到LDAP是用哪个属性来存储用户名的,有可能是uid,也有可能是其他。

但这段代码还有个问题,它只能检查某个用户是否存在,但不能检查它对应的密码是否正确,如何可以同时检查用户名和密码呢?我们修改一下代码,如下:

  1. public int IsAuthenticated(string strUserName, string strPwd)
  1. {
  1. DirectoryEntry entry = new DirectoryEntry("LDAP://127.0.0.1/ou=user,dc=companyname,dc=com","cn=sysuser,ou=systemaccounts,dc=companyname,dc=com", "sysuser", AuthenticationTypes.None);
  1.  
  1. try
  1. {
  1. object native = entry.NativeObject;
  1. DirectorySearcher searcher = new DirectorySearcher(entry);
  1. searcher.Filter = "(cn=" + strUserName + ")";
  1. searcher.PropertiesToLoad.Add("cn");
  1. SearchResultCollection ret = searcher.FindAll();
  1. foreach (SearchResult sr in ret)
  1. {
  1. if (sr != null)
  1. {
  1. string strPath = sr.Path;
  1. int nIndex = strPath.LastIndexOf("/");
  1. if (nIndex > 0)
  1. {
  1. strPath = strPath.Substring(nIndex + 1, strPath.Length - nIndex - 1);
  1. entry = new DirectoryEntry(sr.Path, strPath, strPwd, AuthenticationTypes.None);
  1. try
  1. {
  1. object native1 = entry.NativeObject;
  1. return 0;
  1. }
  1. catch (System.Exception ex)
  1. {
  1. //return 2; //invalid password
  1. }
  1. }
  1. }
  1. }
  1.  
  1. if (ret.Count > 0)
  1. return 2; //invalid password
  1. }
  1. catch (System.Exception ex)
  1. {
  1. throw new Exception("Error authenticating user." + ex.Message);
  1. }
  1. return 1; //invalid user
  1. }

我们用这个用户名和密码create一个DirectoryEntry,如果是有效的,就能create,不是有效地,就会抛出一个异常。

这里我们可以看到,我们还修改了Filter得到的结果,现在得到的记过一个Collection。因为同样的用户名,可能属于不同的group,只用findone,可能只是拿到了一个结果,而这个结果可能恰好就不是我们想要的那个user,所以用collection遍历,就可以万无一失。

这次先讲这么多吧。

[C#]LDAP验证用户名和密码的更多相关文章

  1. LDAP验证用户名和密码

    测试环境:VS2008, NET Framework 3.5 公司打算改用LDAP来存储用户名和密码,现在用C#测试下如何能拿到LDAP中的用户名,并检测用户密码是否正确.即输入用户名和密码,可以检验 ...

  2. Android 设置代理(验证用户名和密码)

    这几天在研究在Android中,解析网页,但是公司内容,链接外网需要代理,并需要验证用户名和密码,十分头疼,网上查了下,没有头绪,最后总算在一个外国博客中看到类似的,记录下 URL url = new ...

  3. django 使用form验证用户名和密码

    form验证可以减少查询数据库,所以代码先预先验证,有问题可以返回给前端显示 1.在users文件夹下新建forms.py文件,用来验证用户名和密码是否为空,密码长度是否大于6 # -*- codin ...

  4. 用SQL Server验证用户名和密码

    用SQL Server验证用户名和密码,从页面输入的用户名和密码与数据库的用户名和密码进行匹配,正确则登入,错误则提醒. <form action="index.jsp" m ...

  5. c# 调用mysql数据库验证用户名和密码

    使用mysql数据库验证用户名和密码时,如果用户名是中文,一直查不到数据 需要把app.config 中修改为 数据库统一设置utf8编码格式,连接数据库的时候设置编码Charset=utf8可以避免 ...

  6. ajax验证用户名和密码

    var user = form.name.value; var password = form.password.value; var url = "chkname.php?user=&qu ...

  7. js 验证用户名和密码是否为空

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"% ...

  8. 验证用户名,密码,验证码,发送alax请求进行登录代码

    //html代码 <div class="layui-form" id="larry_form"> <div class="layu ...

  9. Java 验证用户名、密码

    1. 数据库操作 2.验证用户 2.1. 查询 String sql = String.format("select count(*) from user where name='%s' a ...

随机推荐

  1. Redis教程(八):事务详解

    转载于:http://www.itxuexiwang.com/a/shujukujishu/redis/2016/0216/135.html?1455806987 一.概述: 和众多其它数据库一样,R ...

  2. ClamAV安装使用及API例子

    ClamAV是一款由Sourcefire组织开发的开源杀毒引擎,Sourcefire同时也是Snort入侵检测引擎的所有者.ClamAV提供了一种更为快速灵活的框架用以检测恶意代码和软件产品.可以作为 ...

  3. Oracle的sqlnet.ora与password文件试验

    先看有没有sqlnet.ora [oracle@localhost ~]$ cd $ORACLE_HOME[oracle@localhost dbhome_1]$ cd network[oracle@ ...

  4. #pragma data_seg 共享数据区(转)

    原文地址:http://www.cnblogs.com/CBDoctor/archive/2013/01/26/2878201.html 1)#pragma data_seg()一般用于DLL中.也就 ...

  5. Code Consultation

    Need help architecting or coding your application? You can get technical help with building applicat ...

  6. linux下的依赖关系

    1.一般来说依赖关系可以使得软件较小并且某个lib修复bug以后所有被依赖的软件都能得到好处. 依赖关系下,对于维护也有利有弊,第一,若某个被依赖的软件出现bug或者漏洞,这时候就只需要维护一个软件, ...

  7. ubuntu 16.04 有道词典

    依赖环境 sudo apt install \ python3-pyqt5 \ python3-requests \ python3-xlib \ python3-pil \ tesseract-oc ...

  8. JavaScript学习汇总

    对于JavaScript,还是无法割舍,有心无力,时间总是匆匆,暂且都放在这里吧 javascript中this的使用 写的很不错的一偏文章,简单看了下,mark了吧 原文:http://davids ...

  9. [LeetCode] Serialize and Deserialize Binary Tree

    Serialize and Deserialize Binary Tree Serialization is the process of converting a data structure or ...

  10. Web app 的性能瓶颈与性能调优方法

    1. web app 性能测试工具使用 2. mysql 性能分析与调优方法