1. LDAP简介

  LDAP(轻量级目录访问协议,Lightweight Directory Access Protocol)是实现提供被称为目录服务的信息服务。目录服务是一种特殊的数据库系统,其专门针对读取,浏览和搜索操作进行了特定的优化。目录一般用来包含描述性的,基于属性的信息并支持精细复杂的过滤能力。目录一般不支持通用数据库针对大量更新操作操作需要的复杂的事务管理或回卷策略。而目录服务的更新则一般都非常简单。这种目录可以存储包括个人信息、web链结、jpeg图像等各种信息。为了访问存储在目录中的信息,就需要使用运行在TCP/IP 之上的访问协议—LDAP。

  LDAP目录中的信息是是按照树型结构组织,具体信息存储在条目(entry)的数据结构中。条目相当于关系数据库中表的记录;条目是具有区别名DN (Distinguished Name)的属性(Attribute),DN是用来引用条目的,DN相当于关系数据库表中的关键字(Primary Key)。属性由类型(Type)和一个或多个值(Values)组成,相当于关系数据库中的字段(Field)由字段名和数据类型组成,只是为了方便检索的需要,LDAP中的Type可以有多个Value,而不是关系数据库中为降低数据的冗余性要求实现的各个域必须是不相关的。LDAP中条目的组织一般按照地理位置和组织关系进行组织,非常的直观。LDAP把数据存放在文件中,为提高效率可以使用基于索引的文件数据库,而不是关系数据库。类型的一个例子就是mail,其值将是一个电子邮件地址。

LDAP的信息是以树型结构存储的,在树根一般定义国家(c=CN)或域名(dc=com),在其下则往往定义一个或多个组织 (organization)(o=Acme)或组织单元(organizational units) (ou=People)。一个组织单元可能包含诸如所有雇员、大楼内的所有打印机等信息。此外,LDAP支持对条目能够和必须支持哪些属性进行控制,这是有一个特殊的称为对象类别(objectClass)的属性来实现的。该属性的值决定了该条目必须遵循的一些规则,其规定了该条目能够及至少应该包含哪些属性。例如:inetorgPerson对象类需要支持sn(surname)和cn(common name)属性,但也可以包含可选的如邮件,电话号码等属性。

2. LDAP简称对应

  1. o– organization(组织-公司)
  2. ou – organization unit(组织单元-部门)
  3. c - countryName(国家)
  4. dc - domainComponent(域名)
  5. sn – suer name(真实名称)
  6. cn - common name(常用名称)

3.常见的目录服务软件

    • X.500
    • LDAP
    • Actrive Directory,Microsoft公司
    • NIS

4.AD介绍

.Net提供了专用类操作AD,本文详细介绍使用C#操作AD的方法。

一、系统环境

系统环境:Windows Server 2008 R2, VS2010, .Net Framework 4.0

AD Server:LDAP的server IP

基本DN:OU=user,DC=Company,DC=com

用来登录的管理员:Peter

密码:ab#CD%1234

二、程序

1.  引用

.Net操作AD的类在命名空间System.DirectoryServices下,需要将该类引用进来。

2.  连接

要操作AD需首先连接AD,就象要操作数据先要连接数据库一样。

其中ADPath是要查询组织单元的所在的LDAP,其格式为:LDAP:\\ OU=XX部门,OU=XX公司,DC=域名,DC=COM,如果连接到的AD是在服务器上那么格式写成LDAP:\\XX.XX.XX.XX\ OU=XX部门,OU=XX公司,DC=域名,DC=COM(XX.XX.XX.XX为服务器IP);ADAccount和ADPwd为AD用户的账户和密码,如果是管理员则可以进行任何操作,普通只能进行查询操作。

     de.Path = "LDAP://AD服务器地址/OU=CompanyA,DC=contoso,DC=com";
     de.Username = @"contoso\管理员账号";
    de.Password = "管理员密码";
    private static string DomainName = "VMEX";
private static string LDAPDomain = "DC=VMEX,DC=local";
private static string ADPath = "LDAP://DC=VMEX,DC=local";
//AD管理员帐号
private static string ADUser = "Administrator";
//AD管理员密码
private static string ADPasssWord = "1234@abcd";
/// <summary>
/// 获得DirectoryEntry对象实例,以管理员登陆AD
/// </summary>
/// <returns></returns>
private static DirectoryEntry GetDirectoryObject()
{
DirectoryEntry entry = null;
try
{
entry = new DirectoryEntry("LDAP://10.10.10.16", "Peter", " ab#CD%1234", AuthenticationTypes.Secure);
}
catch (Exception ex)
{
}
return entry;
}

3.  查询

根据各种条件获取具体的用户。下例为根据公共名称获取对象。

/// <summary>
/// 根据用户公共名称取得用户的 对象
/// </summary>
/// <param name="commonName">用户公共名称</param>
/// <returns>如果找到该用户则返回用户的对象,否则返回 null</returns>
public static DirectoryEntry GetDirectoryEntry(string commonName)
{
DirectoryEntry de = GetDirectoryObject();
DirectorySearcher deSearch = new DirectorySearcher(de);
deSearch.Filter = "(&(&(objectCategory=person)(objectClass=user))(cn=" + commonName.Replace("\\", "") + "))";
deSearch.SearchScope = SearchScope.Subtree;
try
{
SearchResult result = deSearch.FindOne();
de = new DirectoryEntry(result.Path);
return de;
}
catch (Exception ex)
{
return null;
}
}

4.  修改用户

修改查询到的Entity的值,修改后将修改记录保存到AD。注意有两种保存属性的方式。具体使用哪种请参考帮助。

1)       直接修改属性

2)       通过invoke来触发AD的内置函数

/// <summary>
/// 修改查询到的用户
/// </summary>
/// <param name="CommonName">通用名(displayName,系统中显示的中文字)</param>
/// <param name="Account">帐户名(如Peter)</param>
/// <param name="organizeName">组织单元名(资讯中心)</param>
/// <param name="password">密码</param>
public static string ChangeADAccount(string CommonName, string Account, string password)
{
//获取对应AD实体
DirectoryEntry user = GetDirectoryEntry( commonName);
try
{
ADHelper.SetProperty(user, " sAMAccountName ", Account);
user.Invoke("SetPassword", new object[] { password });
user.CommitChanges();
}
catch (Exception e)
{
throw e;
}
return user.Path;
} /// <summary>
/// 设置指定的属性值
/// </summary>
/// <param name="de"></param>
/// <param name="propertyName">属性名称?</param>
/// <param name="propertyValue">属性值</param>
public static void SetProperty(DirectoryEntry de, string propertyName, string propertyValue)
{
if (de.Properties.Contains(propertyName))
{
if (String.IsNullOrEmpty(propertyValue))
{
de.Properties[propertyName].RemoveAt(0);
}
else
{
de.Properties[propertyName][0] = propertyValue;
}
}
else
{
if (!String.IsNullOrEmpty(propertyValue))
{
de.Properties[propertyName].Add(propertyValue);
}
}
}

5.  修改OU

1)  获取OU

 DirectoryEntry OUEntry = new DirectoryEntry(GetOrganizeNamePath(OUName), "Peter", " ab#CD%1234", AuthenticationTypes.Secure);
/// <summary>
/// 获得OU的Path
/// </summary>
/// <param name="organizeUnit">OU名</param>
/// <returns></returns>
public static string GetOrganizeNamePath(string organizeUnit)
{
StringBuilder sb = new StringBuilder();
sb.Append(ADPath);
sb.Append("/");
return sb.Append(SplitOrganizeNameToDN(organizeUnit)).ToString();
}

2)  修改OU项

OUEntry.Rename("OU=" + newOUName);

        OUEntry.CommitChanges();

3)  删除OU

DirectoryEntry OUParent = OUEntry.Parent;

        OUParent.Children.Remove(OUEntry);

        OUParent.CommitChanges();

6.  修改组

1)  获取组

 /// <summary>
/// 获取AD组
/// </summary>
/// <param name="groupName"></param>
/// <param name="organizeUnit"></param>
/// <returns></returns>
public static DirectoryEntry GetADGroupInOU(string groupName, string organizeUnit)
{
if (!String.IsNullOrEmpty(groupName))
{
DirectoryEntry de = new DirectoryEntry(GetOrganizeNamePath(organizeUnit) , "Peter", " ab#CD%1234", AuthenticationTypes.Secure); ;
DirectorySearcher deSearch = new DirectorySearcher(de);
deSearch.Filter = "(&(objectClass=group)(cn=" + groupName.Replace("\\", "") + "))";
deSearch.SearchScope = SearchScope.Subtree;
try
{
SearchResult result = deSearch.FindOne();
if (result != null)
{
de = new DirectoryEntry(result.Path, adminName, adminPassword);
}
else
{
return null;
}
return de;
}
catch (Exception ex)
{
return null;
}
}
else
{
return null;
}
}

2)  管理组成员

group.Properties["member"].Add(user.Properties["distinguishedName"].Value);

group.Properties["member"].Remove(user.Properties["distinguishedName"].Value);

三、查看AD User属性结果

在程序中修改了User属性后我们要检验一下是否被修改了,有三种方式查看AD中User属性:

1.  Active Directory Users and Computers

打开Active Directory Users and Computers,选择一个用户,右键单击该用户选择属性显示如下图所示的属性页。在该属性页只能看到一些常用的属性。

2.  Exchange Management Console

打开Exchange Management Console,选择一个用户,右键单击该用户选择属性显示如下图所示的属性页。单击Customer Attributes按钮可以查看自定义的属性。

3.  adsiedit.msc

以上两种方式所看到的属性都不全,要看到所有属性需使用adsiedit.msc工具。

在运行窗口中输入adsiedit.msc后打开本工具。选择一个用户,右键单击该用户选择属性显示如下图所示的属性页。

C#操作Active Directory(AD)详解的更多相关文章

  1. C#操作SQLite方法实例详解

    用 C# 访问 SQLite 入门(1) CC++C#SQLiteFirefox  用 C# 访问 SQLite 入门 (1) SQLite 在 VS C# 环境下的开发,网上已经有很多教程.我也是从 ...

  2. 使用Java操作文本文件的方法详解

    使用Java操作文本文件的方法详解 摘要: 最初java是不支持对文本文件的处理的,为了弥补这个缺憾而引入了Reader和Writer两个类 最初java是不支持对文本文件的处理的,为了弥补这个缺憾而 ...

  3. Python操作redis字符串(String)详解 (三)

    # -*- coding: utf-8 -*- import redis #这个redis不能用,请根据自己的需要修改 r =redis.Redis(host=") 1.SET 命令用于设置 ...

  4. How to setup Active Directory (AD) In Windows Server 2016

    Windows Server 2016 is the newest server operating system released by Microsoft in October 12th, 201 ...

  5. 操作Active Directory C#

    .Net平台操作活动目录Active Directory,使用System.DirectoryServices.ActiveDirectory,主要是User OU 和Group的操作. 代码运行了一 ...

  6. datazen Active Directory AD 配置

    今天苦心经营的datazen 链接AD,文档已经无法吐槽了简单的几句话,根本不够用. 先说一下链接AD 的好处吧, 1 首先免去设置密码的麻烦,因为直接用AD账号的密码. 2 更安全,因为客户可不想自 ...

  7. Yii2.0数据库操作增删改查详解

    1.简单查询: one(): 根据查询结果返回查询的第一条记录. all(): 根据查询结果返回所有记录. count(): 返回记录的数量. sum(): 返回指定列的总数. average():  ...

  8. thinkphp框架中“关联操作”的完整定义详解

    在复杂的关联操作中,如果要给关联定义增加可选的属性,我们可以采用完整定义的方式. 完整定义的格式是: protected $_link = array(     '关联表名1'  =>  arr ...

  9. python数据库操作常用功能使用详解(创建表/插入数据/获取数据)

    实例1.取得MYSQL版本 复制代码 代码如下: # -*- coding: UTF-8 -*-#安装MYSQL DB for pythonimport MySQLdb as mdbcon = Non ...

随机推荐

  1. Intent.Action

    1 Intent.ACTION_MAIN String: android.intent.action.MAIN 标识Activity为一个程序的开始.比较常用. Input:nothing Outpu ...

  2. Android本地JUnit Text

    Android本地JUnit Text 步骤 创建一个和source文件,里面添加和src目录相同的包. 在AndroidManifest.xml文件manifest根节点添加如下文件 <ins ...

  3. sql脚本的格式

    创建表前先判断是否存在 IF OBJECT_ID(N'TableDataDictionary') IS NULL 存储过程头:--=================================== ...

  4. Merge OUTPUT 高级用法综合写的一个MergeTab的存储过程

    因为工作中常用到 合并两张表中的数据,主要是写下来给自己备忘,T-SQL 中 MERGE 的用法 WHEN MATCHED THEN UPDATE -- 中加了 后面要更新的列是否都相等,如果相等就没 ...

  5. js EasyUI前台 全选的实现

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAWcAAAEQCAIAAADj/SKjAAAgAElEQVR4nO1dz48ry1W+/5N3swaFEP ...

  6. 分享一张oracle scan图

  7. ListPreference之entries和entryValues

    在使用PreferenceActivity时,碰到配置文件的ListPreference有两个属性android:entries,android:entryValues.这两个属性其实就和html的o ...

  8. CentOS 7.0 重置root密码

    步骤一,开机时随便按下键盘,进入以下菜单 步骤二: 选择第一项,按e键进行修改 步骤三,定位到 ro( linux 16 or linuxefi ) 步骤四:把ro改成 “rw init=/sysro ...

  9. 看es6 字符串新方法有感

    'x'.repeat(3) // "xxx" 'hello'.repeat(2) // "hellohello" 'na'.repeat(0) // " ...

  10. ng-html 报 不安全 警告解决办法

    app.filter('to_trusted',['$sce',function($sce){ return function(text){ return $sce.trustAsHtml(text) ...