65.9K
CodeProject 正在变化。 阅读更多。
Home

自动管理 AD 组

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.25/5 (6投票s)

2008年1月29日

CPOL

8分钟阅读

viewsIcon

27182

downloadIcon

823

提供了一种创建和管理 AD 组的方法。

引言

我的雇主正在开发一个大型应用程序,该应用程序使用了 Microsoft Reporting Services。我们被告知 Reporting Services 安全性与 Active Directory 配合得很好(正如您可能猜到的那样)。因此,我们提出了一个想法,即通过 Active Directory 来管理我们应用程序的报告安全性,但我们不希望这是一个手动过程。我们需要一种自动化的方法。我们的应用程序管理项目。项目中的人员在项目名册中进行管理。如果我们能以某种方式将我们的项目名册同步到 Active Directory,那么我们就得到了我们想要的东西。

所以,我们需要一个能够从我们的项目名册中提取数据并将其同步到 Active Directory 的东西。因此,我编写了一个组件来完成这项工作:创建和管理 AD 组。

背景

我们认为,除了我们的应用程序,我们组织中的其他各种系统也可能希望简化 AD 组管理。因此,我们想出一个可重用的组件,可以跨所有这些系统使用。我们希望该组件与它同步的任何数据存储完全解耦。这个目标催生了 ADGroupManager 组件。模型附在此文章中。要查看模型,请右键单击并另存为。

ADGroupManager Model - Click image to enlarge

ADGroupManager 组件包含两个主要部分:GroupDefinitionADUpdaterGroupDefinition 提供了一种方式,供调用代码与库进行通信,告知需要同步哪些数据。GroupDefiniton 基本上提供了一个 Add Resource 方法。每当添加资源时,GroupDefinition 负责构建与 AD 中的组结构相匹配的组。GroupDefinition 包含一个 Group 集合。组可以包含组或资源。

组的构建方式取决于 GroupDefinitionMode。我们希望在创建组时具有一定的灵活性,因为我们假设多个系统将使用我们的组件。两种模式基于一个或两个令牌构建扁平组。我们认为一个常见的应用是项目和角色作为两个令牌。第三种模式结合了这两个令牌,但它构建了一个父组,子组属于该父组。在我们的例子中,一个角色级别的组,它将包含所有项目角色级别的组。所有组都以组前缀开头,在我们的例子中是应用程序名称。

一旦构建了 GroupDefinitionADUpdater 就可以执行与 AD 的实际同步。它只有一个 public 方法 SyncGroups()

我还包含了我编写的用于使用我的组件的 Windows 服务,因此您可以看到调用代码的样子。它基于 .NET Timer 执行定时操作。启动时,它会读取一个config 文件以获取开始和停止时间以及运行之间的延迟。它还包含数据存储的连接字符串和查询字符串,以及 ADGroupManager 的可配置参数,例如前缀、模式、AD 容器和路径。它还包含一个名为 Logger 的类,该类基本上只是 .NET EventLog 的包装器。

ADGroupManager 解决方案包含组件的所有代码以及所有单元测试。PSADGroupWinService 解决方案包含服务(调用代码)的所有代码。我设想我所有的类和方法都是 internal 的,除了我设想的 public interface 。为了适应我的测试,我必须对此进行一些小修改。RTF 文档是 ADGroupManager 的完整文档。它包含本文档中的模型图以及有关每个方法、属性、类、成员、枚举的信息。应有尽有。

Using the Code

GroupDefiniton

GroupDefinition 依靠以下项才能成功运行

  • 一种决定如何创建组的模式
  • 用作组名一部分的组前缀
  • LDAP 路径(对于 GroupDefinition 并非真正需要,但对于 ADUpdater 需要)
  • LDAP 容器。默认是 Users,但您可以指定自己的(同样适用于 ADUpdater

一旦所有这些部分就位,就可以添加资源了。这有两种重载:AddResourceToGroupDefinition(string groupToken, string userId)AddResourceToGroupDefinition(string groupToken, string userId, string subGroupToken)。根据您的 GroupDefinitionMode,只有其中一个重载可供调用代码使用。调用与特定模式不匹配的重载将导致 PolicyException。此外,userid 必须只包含用户 ID,而不是以域为前缀,因此 DOMAIN\userid 是无效的。

根据模式,组被构建成一个扁平列表,或者在 PrefixExtendedGroupMode 的情况下,会创建父组。因此,public API 最终会委托给 AddResourceToFlatGroup()AddResourceViaPrefixExtendedGroupMode()。组名根据模式定义得非常清楚,要么是 PrefixToken1,要么是 PrefixToken1Token2,并且可能有一个父组 PrefixToken2。因此,比较是基于组名进行的。资源的添加方式类似,仅添加到子组。组在 AD 中只能存在一次,这个范例在 GroupDefinition 中得到保持。

ADUpdater

ADUpdater 只需要一件事:一个 GroupDefinition。目标是创建它,使其包含创建 AD 组所需的一切。这样它就可以更简单。它只有一个 public 方法:SyncGroups()

ADUpdater 遵循与定义相同的约定,委托给 SyncFlatListGroups()SyncExtendedListGroups()。这些方法基本上会检查组是否存在于 AD 中,如果不存在,则创建该组。在组就绪后,会将用户添加到组中。这是通过将组和用户在 AD 中表示为 .NET DirectoryEntry 并将用户添加到组的成员属性来实现的。这可以在 AddResourcesToADGroup() 中看到。组也以类似的方式添加到其他组中。这些同步方法利用各种执行单独职责的方法,例如创建组、从组中移除用户、检查组是否包含用户、组是否存在等。

定义必须始终是需要同步的数据的完整定义。不会应用增量更新,因为 SyncGroups() 承担了移除不再属于的用户的附加职责。所有更新都会在组上进行,然后执行提交。目前,该组件没有提供移除组的机制。这有几个原因,无论是没有确定的方法来识别需要移除的组,还是考虑到组可能被其他系统使用,组是否应该被删除。

组必须有一个组类型。我提供了一个名为 ADGroupTypeenum,它镜像了可用的 AD 组类型。目前我只使用了 DomainLocal 类型。我相信它能满足我们的需求。我的理解是,这些类型是标志,可以组合在一起。

Group 和 Resource

这些基本上只是数据容器。Group 确实有一些 add/remove 方法来管理其集合,但无关紧要。

调用代码

本文中的调用代码是一个 Windows 服务,但也可以是任何东西。我用一个简单的小 Windows 应用程序(带有一个按钮和一个标签)对其进行了广泛的测试。该服务从config 文件中读取以下内容:

  • EnableLogingTrue/False,取决于您是否要写入事件日志
  • GroupDefinitionMode,组的创建方式
  • PrefixName,组前缀(我们的应用程序名称)
  • ADContainer,组将被放置在 AD 中的容器
  • ADPath,AD 所在的根 LDAP 路径
  • StartTime,服务在此时间之前不会执行,每天
  • EndTime,服务在此时间之后不会执行,每天
  • DelayInHours,与分钟结合以提供同步之间的延迟
  • DelayInMinutes,与小时结合以提供同步之间的延迟
  • ConnectionString,到数据存储
  • QueryString,适当的数据

服务启动时,会读取配置并初始化服务。配置必须满足有效的条件才能使服务执行。ConfigurationIsValid 属性可确保这一点。当延迟过后,计时器会响起,IsTimeToExecute 属性会根据开始和结束时间以及延迟验证是否是执行时间。如果同步正在执行,则不会启动二次同步。日志记录到应用程序事件日志。我为此编写了一个名为 Logger 的包装器。我留出了配置其他事件日志的空间,但目前对应用程序感到满意。

请注意,根据提交的内容,服务解决方案设置为使用 Local System 帐户来运行服务。您需要确保服务在具有写入 ADAM 或 AD 权限的帐户下运行。我是通过令人恼火的方式发现这一点的。

关注点

我不知道有哪个网络管理员会允许您随意创建 AD 组,所以我建议您联系他们,看看他们是否可以为您设置开发环境。如果您无法让他们这样做,请尝试改用 ADAM。我试过了,效果很好。不幸的是,我在尝试在我的机器上安装它时遇到了很多麻烦。因此,作为本文的一部分,我包含了一个关于 ADAM 安装的 Microsoft 操作指南(ADAM_Step-by-Step_Guide)以及我编写的文档(ADAM How To),该文档是在与 Microsoft 进行长时间支持电话后编写的。ADAM 可以在 这里 下载,还有一个很棒的 AD 浏览器 这里

我目前没有对组件进行更新的计划,但我会考虑移除旧组的可能性,并努力为组制定一个显示名称,以便最终用户更容易识别组。

我不是 AD 专家。在这之前,我从未编写过任何针对 AD 的代码。所以如果你注意到任何严重的错误,请告诉我。话虽如此,代码是有效的。

历史

  • 2008 年 1 月 29 日:此代码的初始发布版本为 0.0.1.0
© . All rights reserved.