C#通过LDAP访问目录服务
C#通过LDAP访问目录服务
本文介绍如何编写C#程序通过LDAP协议访问微软目录服务获得用户在目录中的属性信息。在开始部分先简单句介绍LDAP协议,然后是技术比较及实现部分。
目录
- 什么是LDAP?
- 简介
- 概述
- 协议内容
- 产品
- 查询用户信息
- 用途
什么是LDAP?
简介
LDAP是轻型目录访问协议(Lightweight Directory Access Protocol,/ˈɛldæp/),是一个开放的、中立的、工业标准的应用协议,通过IP协议提供访问控制和维护分布式信息的目录信息访问服务。
目录服务在开发内部网路和与互联网应用共享用户(用户组织)、系统、网络、服务和应用的过程中占据了重要地位。例如,目录服务提供了组织有序的记录集合,通常有层级结构,例如公司电子邮件目录。同理,也提供包含了地址和电话号码的电话簿。
LDAP由互联网工程任务组(IETF)的文档RFC定义,使用了描述语言ASN.1定义。最新的版本是版本3,由RFC 4511所定义。例如,一个用语言描述的LDAP的搜索如:“在公司邮件目录中搜索公司位于那什维尔名字中含有“Jessy”的有邮件地址的所有人。请返回他们的全名,电子邮件,头衔和简述。”
LDAP的一个常用用途是单点登录,用户可以在多个服务中使用同一个密码,通常用于公司内部网站的登录中(这样他们可以在公司计算机上登录一次,便可以自动在公司内部网上登录)。
LDAP基于X.500标准的子集。因为这个关系,LDAP有时被称为X.500-lite。
概述
鉴于原先的目录访问协议(Directory Access Protocol即DAP)对于简单的互联网客户端使用太复杂,IETF设计并指定LDAP做为使用X.500目录的更好的途径。LDAP在TCP/IP之上定义了一个相对简单的升级和搜索目录的协议。
常用词"LDAP目录"可能会被误解,而实际并没有"LDAP目录"这么一个目录种类。通常可以用它来描述任何使用LDAP协议访问并能用X.500标识符标识目录中对象的目录。
协议内容
LDAP目录与普通数据库结构的主要不同之处在于数据的组织方式,它是一种有层次的、树形结构。所有条目的属性的定义是对象类(object class)的组成部分,并组成在一起构成结构(schema);那些在组织内代表个人的结构被命名为白页结构(white pages schema)。数据库内的每个条目都与若干对象类联系,而这些对象类决定了一个属性是否为可选和它保存哪些类型的信息。属性的名字一般是一个易于记忆的字符串,例如用cn为通用名(common name)命名,而"mail"代表e-mail地址。属性取值依赖于其类型,并且LDAPv3中一般非二进制值都遵从UTF-8字符串语法。例如,mail属性包含值“user@example.com”;jpegPhotos属性一般包含JPEG/JFIF格式的图片。
LDAP目录条目可描述一个层次结构,这个结构可以反映一个政治、地理或者组织的范畴。在原始的X.500模型中,反应国家的条目位于树的顶端;接着是州或者民族组织。典型的LDAP配置使用DNS名称作为树形结构的顶端,下列是代表人、文档、组织单元、打印机和其他任何事务的条目。
LDAP影响了后续的Internet协议,包括新版本的X.500、Directory Services Markup Language (DSML)、Service Provisioning Markup Language (SPML)和Service Location Protocol.
产品
LDAP从下面厂商获得广泛支持:
- Apache - Apache Directory Server
- Apple(苹果) - Open Directory
- AT&T
- Banyan
- HP(惠普)
- IBM - IBM Lotus
- ISODE - M-Vault Server
- Microsoft(微软) - Active Directory
- Netscape(网景) - Sun Microsystems和Red Hat的产品
- Novell - eDirectory
- OctetString - VDE Server
- Oracle(甲骨文) - Oracle Internet Directory
- Red Hat(红帽) - Fedora Directory Server
- Siemens(西门子) - DirX Server
- Sun - iPlanet Directory Server
此外还有开源/自由软件的实现——如Open LDAP、Apache HTTP Server使用代理服务器(通过模块mod_proxy)支持LDAP。
查询用户信息
技术选型
微软Windows活动目录的目录服务还是通过微软的技术框架来实现,无论从安全性和稳定性上都会有一定的保证,所以我们采用C#,当然你也可以使用C++实现,相信会有更好的性能提升。
目录服务程序集
这里我们介绍一下目录服务相关的程序集:
| 名称 | 说明 |
|---|---|
| System.DirectoryServices | 利用System.DirectoryServices命名空间,可以方便地从托管代码中访问AD域服务。 该命名空间包含两个组件类,即DirectoryEntry和DirectorySearcher,它们使用AD服务接口 (ADSI) 技术。 ADSI是Microsoft 提供的一组接口,作为使用各种网络提供程序的灵活的工具。 无论网络有多大,ADSI 都可以使管理员能够相对容易地定位和管理网络上的资源。 |
| System.DirectoryServices.AccountManagement | 命名空间提供了统一的访问和用户操作、计算机和组安全原则(在多个主要存储):活动目录域服务 (AD DS)、 活动目录轻量级目录服务 (AD LDS)和机器 SAM (MSAM)。 管理独立于 命名空间的目录对象。 |
| System.DirectoryServices.ActiveDirectory | 命名空间提供一个围绕Microsoft AD服务任务构建的高级别抽象对象模型。AD服务概念(例如,林、域、站点、子网、分区和架构)是此对象模型的一部分。 |
| System.DirectoryServices.Protocols | 命名空间提供在轻量目录访问协议 (LDAP) 3 版 (V3) 和目录服务标记语言 (DSML) 2.0 版 (V2) 标准中定义的方法。 |
两种方法的实现与比较
为了获得用户的目录信息,看来我们需要使用的是前两个程序集和名称空间。
使用System.DirectoryServices.AccountManagement获取用户信息示例:
public DirectoryEntry GetEntryByUsername(string username)
{
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, domain);
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, username);
DirectoryEntry entry = user.GetUnderlyingObject() as DirectoryEntry;
return entry;
}
第一次运行花费时间630ms
还有一种方法是直接使用目录搜索
public SearchResult GetEntryByUsername(string username)
{
DirectorySearcher search = new DirectorySearcher();
search.Filter = $"(&(objectClass=user)(sAMAccountName={username}))";
SearchResult result = search.FindOne();
}
第一次运行花费时间355ms
而且后续处理的事件花费差异也很大,使用DirectoryEntry获得的对象,所有属性还需要按其结构进行遍历:
public static void ShowProperties(DirectoryEntry entry)
{
PropertyCollection props = entry.Properties;
foreach (string k in props.PropertyNames)
{
Console.WriteLine("{0}: {1}", k, props[k].Value);
if (props[k].Value is Array)
{
Array arr = (Array)props[k].Value;
foreach (object obj in arr)
{
Console.WriteLine(" Item: " + obj + " Type: " + obj.GetType().Name);
}
}
}
}
而通过DirectorySearcher查询,不但查询速度快,结果似乎也是直接缓存中读出来的,高效快速。
if (result != null)
{
// user exists, cycle through LDAP fields (cn, telephonenumber etc.)
ResultPropertyCollection fields = result.Properties;
foreach (String ldapField in fields.PropertyNames)
{
// cycle through objects in each field e.g. group membership
// (for many fields there will only be one object such as name)
foreach (Object myCollection in fields[ldapField])
Console.WriteLine(String.Format("{0,-20} : {1}",
ldapField, myCollection.ToString()));
}
}
所以这里推荐使用DirectorySearcher直接进行目录对象(不仅限于用户,还有组织单元、计算机、其它设备等信息)的搜索和详细信息输出,效率会提升不少。
用途
利用Microsoft目录服务管理的公司,可以通过目录属性进行网络、设备等进行基于角色的访问控制,通过不同的AD组或设置目录属性,采用不同的管理策略。而IT经常需要对此过程进行自动化处理,所以通过LDAP进行目录服务数据的更改和访问就必不可少,还可以自动化权限(AD组、属性)的复查流程,减少组织和企业管理的人工成本。
C#通过LDAP访问目录服务的更多相关文章
- LDAP目录服务
LDAP目录服务 1.ldap目录服务介绍: 目录是一类为了浏览和搜索数据而设计的特殊的数据库,目录服务是按树状形式存储信息的,目录包含基于属性的描述信息,并且支持高级的过滤功能,一般来说,目录不支持 ...
- 轻型目录访问协议 ldap 公司内部网站的登录 单点登录
https://zh.wikipedia.org/wiki/轻型目录访问协议 轻型目录访问协议(英文:Lightweight Directory Access Protocol,缩写:LDAP,/ˈɛ ...
- LDAP未授权访问学习
LDAP未授权访问学习 一.LDAP 介绍 LDAP的全称为Lightweight Directory Access Protocol(轻量级目录访问协议), 基于X.500标准, 支持 TCP/IP ...
- JNDI 与 LDAP
对于众多接口服务.协议.互联网名称,总会遇到感到熟悉,但是时间一长就会忘记,所以还是要自己整理一下,加强记忆,当然最好的方式还是动手实践. JNDI : 全称:JAVA NAMING AND Dire ...
- java访问ad域
1.活动目录(AD) Active Directory 是用于 Windows Server 的目录服务.它存储着网络上各种对象的有关信息,并使该信息易于管理员和用户查找及使用.Active Dire ...
- Spring Security LDAP简介
1.概述 在本快速教程中,我们将学习如何设置Spring Security LDAP. 在我们开始之前,了解一下LDAP是什么? - 它代表轻量级目录访问协议.它是一种开放的,与供应商无关的协议,用于 ...
- Ldap 从入门到放弃(一)
OpenLDAP 2.4版本 快速入门 本文内容是自己通过官网文档.网络和相关书籍学习和理解并整理成文档,其中有错误或者疑问请在文章下方留言. 一.Introduction to OpenLDAP D ...
- GJM :用JIRA管理你的项目(三)基于LDAP用户管理 [转载]
感谢您的阅读.喜欢的.有用的就请大哥大嫂们高抬贵手"推荐一下"吧!你的精神支持是博主强大的写作动力以及转载收藏动力.欢迎转载! 版权声明:本文原创发表于 [请点击连接前往] ,未经 ...
- java 访问活动目录代码
package demo; import java.util.Hashtable; import javax.naming.Context; import javax.naming.NamingEnu ...
随机推荐
- 安装java环境与eclipse
一.今天安装了java环境和eclipse 二.大道至简学了前三章(前两章)问题不大还好理解 第三章有些东西很懵 1.进入网址www.oracle.com,点击resource(资源) 点击softw ...
- js和C# 编码 解码
C#中对URL编码的方法... 编码:Server.UrlEncode(string) 解码:Server.UrlDecode(string) HttpUtility.UrlEncode(string ...
- qt(一)
一.Qt安装 qt离线安装地址:http://download.qt.io/archive/qt/ 参考教程:https://blog.csdn.net/u013934107/article/deta ...
- MyBatis 使用(XML版本)
一.MyBatis相关概念 对象 / 关系数据库映射(ORM) ORM全称Object/Relation Mapping:表示对象-关系映射的缩写 ORM完成⾯向对象的编程语⾔到关系数据库的映射.当O ...
- vue项目环境搭建(webpack4从零搭建)--仅个人记录
一.nodejs环境搭建 首先需要下载node.js(推荐直接官网找最新的版本),下载完成后会自带npm包管理工具,打开cmd命令行界面,输入npm -v .node -v检查node.js与npm是 ...
- Chapter02 Java概述
Chapter02 Java概述 目录 Chapter02 Java概述 2.1 什么是程序 程序: 2.2 Java的重要特点 2.3 Java 运行机制及运行过程 2.3.1 Java 语言的特点 ...
- LeetCode-129-求根节点到叶节点数字之和
求根节点到叶节点数字之和 题目描述:给你一个二叉树的根节点 root ,树中每个节点都存放有一个 0 到 9 之间的数字. 每条从根节点到叶节点的路径都代表一个数字: 例如,从根节点到叶节点的路径 1 ...
- Solon 1.6.30 发布,更现代感的应用开发框架
相对于 Spring Boot 和 Spring Cloud 的项目 启动快 5 - 10 倍 qps 高 2- 3 倍 运行时内存节省 1/3 ~ 1/2 打包可以缩小到 1/2 ~ 1/10(比如 ...
- SQL从零到迅速精通【触发器】
essay from:http://www.cnblogs.com/hoojo/archive/2011/07/20/2111316.html 触发器就类似一个小账本,记录了你在数据库做了哪些操作,可 ...
- laravel7 H-ui模板ajax软删除
1:HTML 书写 {{-- 不能自己删除自己的按钮出现 $item循环的值,$auth检测函数 --}} @if(auth()->id()!=$item->id) <a title ...