LDAP验证用户名和密码
测试环境: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,代码如下:
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); try
{
object native = entry.NativeObject;
return true;
}
catch (System.Exception ex)
{
throw new Exception("Error authenticating user." + ex.Message);
}
return false;
其中参数AuthenticationTypes.None一定要有,测试的时候没有加这个,结果一直连不到server。
二、列举所有user
现在能连接到LDAP了,我们需要取出公司的所有User,代码如下:
public List<string> EnumerateOU()
{
List<string> lst = new List<string>();
DirectoryEntry entry = newDirectoryEntry("LDAP://127.0.01/ou=user,dc=companyname,dc=com","cn=sysuser,ou=systemaccounts,dc=companyname,dc=com","sysuser", AuthenticationTypes.None); try
{
object native = entry.NativeObject;
DirectorySearcher searcher = new DirectorySearcher(entry);
searcher.Filter = "(objectClass=account)";
searcher.PropertiesToLoad.Add("cn");
SearchResultCollection ret = searcher.FindAll();
foreach (SearchResult sr in ret)
{
if (sr != null)
{
lst.Add(sr.Properties["cn"][].ToString());
}
}
}
catch (System.Exception ex)
{
}
return lst;
}
这里声明DirectoryEntry的LDAP server很重要。
LDAP://127.0.0.1/ou=user,….这个是可以取得数据的地址。如果这里ou为其他值,则拿到的就是另外一些数据了。
注意:ou=user…这句是每个公司的规则都不一样,不一定就是ou=user,主要是遵循自己公司的规定。
所有员工应该有个共同的属性,就拿这个共同的属性出来。下面的searcher.Filter也是这样,所有的员工都有个objectClass,它的值可以有多个,但一定都有个值=account,根绝这个规则,我们就可以拿出所有account了。
cn是什么呢?也是LDAP的一个属性,这里cn里面存储的是员工姓名。如果公司的设置不是如此,如何得知哪个node里存储的是什么东东呢?
我们可以将循环改成这样:
foreach (SearchResult sr in ret)
{
foreach (string key in sr.Properties.PropertyNames)
{
foreach (object val in sr.Properties[key])
{
string strTmp = key + " = " + val;
Debug.WriteLine(strTmp);
}
}
}
这样你就可以看到所有属性和它存储的value了。
三、检验某个user name是否存在以及password是否正确。
现在我们来检测一下某个用户名是否存在:
public int IsAuthenticated(string strUserName, string strPwd)
{
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); try
{
object native = entry.NativeObject;
DirectorySearcher searcher = new DirectorySearcher(entry);
searcher.Filter = "(cn=" + strUserName + ")";
searcher.PropertiesToLoad.Add("cn");
SearchResult ret = searcher.FindOne(); if (sr != null)
return ; //succeed. }
catch (System.Exception ex)
{
}
return ; //invalid user
}
这样我们就可以检测到某个用户名是否存在了。这里我们用的Filter是cn=username,实际应用时,要检查自己用到LDAP是用哪个属性来存储用户名的,有可能是uid,也有可能是其他。
但这段代码还有个问题,它只能检查某个用户是否存在,但不能检查它对应的密码是否正确,如何可以同时检查用户名和密码呢?我们修改一下代码,如下:
public int IsAuthenticated(string strUserName, string strPwd)
{
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); try
{
object native = entry.NativeObject;
DirectorySearcher searcher = new DirectorySearcher(entry);
searcher.Filter = "(cn=" + strUserName + ")";
searcher.PropertiesToLoad.Add("cn");
SearchResultCollection ret = searcher.FindAll();
foreach (SearchResult sr in ret)
{
if (sr != null)
{
string strPath = sr.Path;
int nIndex = strPath.LastIndexOf("/");
if (nIndex > )
{
strPath = strPath.Substring(nIndex + , strPath.Length - nIndex - );
entry = new DirectoryEntry(sr.Path, strPath, strPwd, AuthenticationTypes.None);
try
{
object native1 = entry.NativeObject;
return ;
}
catch (System.Exception ex)
{
//return 2; //invalid password
}
}
}
} if (ret.Count > )
return ; //invalid password
}
catch (System.Exception ex)
{
throw new Exception("Error authenticating user." + ex.Message);
}
return ; //invalid user
}
我们用这个用户名和密码create一个DirectoryEntry,如果是有效的,就能create,不是有效地,就会抛出一个异常。
这里我们可以看到,我们还修改了Filter得到的结果,现在得到的记过一个Collection。因为同样的用户名,可能属于不同的group,只用findone,可能只是拿到了一个结果,而这个结果可能恰好就不是我们想要的那个user,所以用collection遍历,就可以万无一失。
这次先讲这么多吧。
以上文章转载于:http://oliverpp.blog.163.com/blog/static/158016201211128029483/
LDAP验证用户名和密码的更多相关文章
- [C#]LDAP验证用户名和密码
测试环境:VS2008, NET Framework 3.5 公司打算改用LDAP来存储用户名和密码,现在用C#测试下如何能拿到LDAP中的用户名,并检测用户密码是否正确.即输入用户名和密码,可以检验 ...
- Android 设置代理(验证用户名和密码)
这几天在研究在Android中,解析网页,但是公司内容,链接外网需要代理,并需要验证用户名和密码,十分头疼,网上查了下,没有头绪,最后总算在一个外国博客中看到类似的,记录下 URL url = new ...
- django 使用form验证用户名和密码
form验证可以减少查询数据库,所以代码先预先验证,有问题可以返回给前端显示 1.在users文件夹下新建forms.py文件,用来验证用户名和密码是否为空,密码长度是否大于6 # -*- codin ...
- 用SQL Server验证用户名和密码
用SQL Server验证用户名和密码,从页面输入的用户名和密码与数据库的用户名和密码进行匹配,正确则登入,错误则提醒. <form action="index.jsp" m ...
- c# 调用mysql数据库验证用户名和密码
使用mysql数据库验证用户名和密码时,如果用户名是中文,一直查不到数据 需要把app.config 中修改为 数据库统一设置utf8编码格式,连接数据库的时候设置编码Charset=utf8可以避免 ...
- ajax验证用户名和密码
var user = form.name.value; var password = form.password.value; var url = "chkname.php?user=&qu ...
- js 验证用户名和密码是否为空
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"% ...
- 验证用户名,密码,验证码,发送alax请求进行登录代码
//html代码 <div class="layui-form" id="larry_form"> <div class="layu ...
- Java 验证用户名、密码
1. 数据库操作 2.验证用户 2.1. 查询 String sql = String.format("select count(*) from user where name='%s' a ...
随机推荐
- SQL Server 中@@IDENTITY的用法
原文地址:http://www.studyofnet.com/news/145.html 本文导读:@@IDENTITY是返回上次插入的标识值,标识值一般指的是自动增长值.但是如果想只返回插入到当前作 ...
- 量身定制顺美男女西服、衬衫、大衣、T恤等 - 北京58同城
量身定制顺美男女西服.衬衫.大衣.T恤等 - 北京58同城 量身定制顺美男女西服.衬衫.大衣.T恤等 发布时间:2014-04-11浏览2次
- AndroidUI 引导页面的使用
一个应用程序都少不了欢迎页面和引导页面,本文主要讲如何制作一个引页面: 首页所有的目录结构: 新建Welcome引导页面和Activity: <RelativeLayout xmlns:andr ...
- 280行代码:Javascript 写的2048游戏
2048 原作者就是用Js写的,一直想尝试,但久久未动手. 昨天教学生学习JS代码.最好还是就做个有趣的游戏好了.2048这么火,是一个不错的选择. 思路: 1. 数组 ,2维数组4x4 2. 移动算 ...
- C#中各种计时器
1.使用 Stopwatch 类 (System.Diagnostics.Stopwatch) Stopwatch 实例可以测量一个时间间隔的运行时间,也可以测量多个时间间隔的总运行时间.在典型的 S ...
- php,ajax登陆退出
利用ajax可以做到页面无刷新登陆. 运行效果 目录结构 site/ css/ images/ js/ site/css/bootstrap.css(bootstrap样式表) site/js/boo ...
- matlab差分算法
今天实现了<一类求解方程全部根的改进差分进化算法>(by 宁桂英,周永权),虽然最后的实现结果并没有文中分析的那么好,但是本文依然是给了一个求解多项式全部实根的基本思路.思路是对的,利用了 ...
- floyd学习中
#include<iostream> #include<math.h> #include<stdio.h> using namespace std; //long ...
- C++, const:
问题: const成员函数和普通成员函数可以是同名同参数吗? 可以,这是一种函数的重载. const成员函数可不可以修改对象的成员变量的值? 不可以修改.//error C3490: ...
- QF——关于iOS的强引用,弱引用及strong,retain,copy,weak,assignd的关系
强引用和弱引用: 我们已经知道OC中的内存管理是通过“引用计数器”来实现的.一个对象的生命周期取决于它是否还被其他对象引用(是否retainCount=0).但在有些情况下,我们并不希望对象的销毁时间 ...