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 ...
随机推荐
- 使用http-server 快速的开启一个静态服务器
在本地安装好了nodejs后我们可以使用一个命令快速开启一个服务器: 命令界面进入到根目录(存放静态网页的文件夹) //方式一 npx http-server //默认 8080端口 //方式二 np ...
- ssh执行命令或者脚本里最好先加上 source /etc/profile
记: 写一次shell脚本,发现总提示 找不到JAVA_HOME .明明已经配了环境变量,并且java -version也已经能输出信息,但就是提示. 后来在 脚本中加入第一句代码 source /e ...
- FaE:基于符号知识的适应性和可解释的神经记忆
原创作者 | 朱林 论文解读: Facts as Experts: Adaptable and Interpretable Neural Memory over Symbolic Knowledge ...
- 关于SQL优化的辟谣
列举一些关于 SQL 语句的谣言,避免一些生瓜蛋子面试的时候被另外一群生瓜蛋子的 SQL 优化宝典给坑了. 以下所有内容都是 SQL Server 中的,其他数据库只能参考和借鉴 一.全表扫描 全表扫 ...
- [2022-2-26] OICLASS-USACO提高组模拟赛 C·Convoluted Intervals S
这道题非常简单啊,我看很多人都做出来了,张林昨天也讲的很明白了,那我来简单写一下: 暴力思路(10pts) 我们发现,我们只需要模拟画出一个图然后进行暴力枚举就行了. 差分+桶+加乘原理思路(100p ...
- HelloWorld:通过demo,构建黑盒模型
在<源码阅读四步走,这才是阅读源码的正确姿势>一文中,给出了源码阅读的完整步骤. 本篇是<如何高效阅读源码>专题的第四篇,正式开始讲解阅读源码的具体方法! 程序界有个老传统,学 ...
- laravel7 百度智能云检测图片是否合规
APP 文件下建一个Libs目录建一个BaiduService文件,需要检测引入进行调用即可 BaiduService文件内容如下 <?php namespace App\Libs; use A ...
- 11 Java的方法 递归
6.递归 A方法调用B方法,我们很容易理解! 递归就是:A方法调用A方法!就是自己调用自己 利用递归可以用简单的程序来解决一些复杂的问题. 它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较 ...
- 云原生技术赋能ISV实现应用现代化
日前,由BP商业伙伴主办,中国开源云联盟和云原生应用现代化联盟协办的2021-2022云计算生态峰会成功举办.头部ISV代表.最终用户和云原生技术专家等与会各方围绕"云原生技术赋能ISV&q ...
- CF498B题解
咋黑色啊,这不是看到数据范围就去想 \(O(nT)\) 的做法吗? 然后仔细想想最靠谱的就是 DP. 设 \(dp[n][T]\) 表示听完第 \(n\) 首歌,总共听了 \(T\) 秒. 很明显有 ...