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

Active Directory 对象导航器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.67/5 (19投票s)

2005年4月26日

4分钟阅读

viewsIcon

271295

downloadIcon

6363

一篇介绍如何连接到 Active Directory 数据库的文章。

Application Image

引言

首先,我想向您介绍导致我找到这个解决方案的问题。 我需要针对 Active Directory (AD) 数据库进行身份验证,但没有找到面向对象的方法。 我发现自己陷入了困境。 如何以不违背我们的三层面向对象架构的方式使用 Active Directory 对象树?

所以我决定我必须抽象应用程序对整个 AD 层的用法。 为此,我需要一个框架,它允许我像浏览 XML 文件一样浏览 AD 对象(我知道这只是一个粗略的比较!)。

背景

我发现了许多关于如何在 AD 上获取此属性或如何获取该属性的文章,但实际上没有一篇文章真正教过如何使用 LDAP 语言。 所以我很难弄清楚如何通过 LDAP 查询访问一个对象。

让我说,我并不打算构建一个 AD 管理器,而且在我的 AD 对象导航器中,我甚至不允许您更改属性(尽管您可以使用 OriginalDirectoryEntry 属性)。

我的目的是向您(读者)提供有关如何使用 AD 数据库的基础知识,并构建一个框架,用于获取用户、组、容器和组织单元,如果您像我一样,计划针对 Active Directory 数据库进行身份验证(并计划将 AD 用户用作应用程序的用户)。

使用代码

我在源代码中(在Doc\ 目录中)包含了一个 Windows HTML 帮助文件,其中详细解释了框架中的每个类和函数。

我在 LoadUser 函数中注释了属性,以便它加载得更快,但如果您需要有关用户的更多信息,只需取消注释或向其中添加其他属性即可。 如果它对您有所帮助以及您添加了什么,请告诉我。

LoadUser 方法

//C#
u = new Objects.User();
u.Id = de.NativeGuid;
u.UserName = getStringProperty(de.Properties,"sAMAccountName");
u.Email = getStringProperty(de.Properties,"userPrincipalName");
//u.GivenName = getStringProperty(de.Properties,"givenName");
u.OriginalDirectoryEntry = de;
if (de.Properties["useraccountcontrol"].Value != null)
{
    if (((int)de.Properties["useraccountcontrol"].Value & 2) == 0)
    {
        u.Enabled = true;
    }
    else
    {
        u.Enabled = false;
    }
}
else
{
    u.Enabled = false;
}
//u.AdditionalPhoneNumbers = 
//             getStringArrayProperty(de.Properties,"otherTelephone");
//u.AdditionalHomePages = getStringArrayProperty(de.Properties,"url");
//u.City = getStringProperty(de.Properties,"l");
//u.Country = getStringProperty(de.Properties,"c");
//u.Description = getStringProperty(de.Properties,"description");
u.DisplayName = getStringProperty(de.Properties,"displayName");
//u.HomePage = getStringProperty(de.Properties,"wWWHomePage");
//u.Initials = getStringProperty(de.Properties,"initials");
//u.PhysicalDeliveryOfficeName = 
//     getStringProperty(de.Properties,"physicalDeliveryOfficeName");
//u.PostOfficeBox = getStringProperty(de.Properties,"postOfficeBox");
//u.State = getStringProperty(de.Properties,"st");
//u.StreetAddress = getStringProperty(de.Properties,"streetAddress");
//u.TelephoneNumber = getStringProperty(de.Properties,"telephoneNumber");

您应该知道的另一件事是,为了易于使用,我在框架中添加了三个常量:DEFAULTDOMAINDEFAULTUSERNAMEDEFAULTPASSWORD。 这些常量用于框架函数,因此您不必将它们作为参数传递。 虽然它们被用作模拟数据,但它们可以设置为 nothing(我不建议这样做!)。 这些常量位于 ADManager 类中。

#region Constants
    const string DEFAULTDOMAIN = "yourDomain";
    const string DEFAULTUSERNAME = "yourUserName";
    const string DEFAULTPASSWORD = "yourPassword";
#endregion

我将解释您希望使用此框架的最常见情况

针对 Active Directory 对用户进行身份验证

'VB.NET
Public Function ValidateUser(ByVal username as _
          string, ByVal password as string) as boolean
  Dim u as BVA.ActiveDirectory.Navigator.Objects.User = _
     BVA.ActiveDirectory.Navigator.Business.AdManager.GetUser(username,password)
  return (u is nothing)
End Function
//C#
public bool ValidateUser(string username, string password)
{
  BVA.ActiveDirectory.Navigator.Objects.User u = 
    BVA.ActiveDirectory.Navigator.Business.AdManager.GetUser(username,password);
  return (u==null);
}

获取用户所属的组

'VB.NET
Public Function MemberShips(ByVal username as string, _
      ByVal password as string) as _
      BVA.ActiveDirectory.Navigator.Objects.GroupCollection
  Dim u as BVA.ActiveDirectory.Navigator.Objects.User = _
    BVA.ActiveDirectory.Navigator.Business.AdManager.GetUser(username,password)
  return u.MemberOf
End Function
//C#
public BVA.ActiveDirectory.Navigator.Objects.GroupCollection 
                MemberShips(string username, string password)
{
  BVA.ActiveDirectory.Navigator.Objects.User u =
    BVA.ActiveDirectory.Navigator.Business.AdManager.GetUser(username,password);
  return (u.MemberOf);
}

获取确定组中的用户

(SID 是每个 AD 对象在 AD 数据库中都有的唯一 ID。)

'VB.NET
Public Function Members(ByVal SID as String) as _
          BVA.ActiveDirectory.Navigator.Objects.UserCollection
  Dim g as BVA.ActiveDirectory.Navigator.Objects.Group = _
    BVA.ActiveDirectory.Navigator.Business.AdManager.GetGroup(SID)
  return g.Members
End Function
//C#
public BVA.ActiveDirectory.Navigator.Objects.GroupCollection 
                                          Members(string SID)
{
  BVA.ActiveDirectory.Navigator.Objects.Group g = 
     BVA.ActiveDirectory.Navigator.Business.AdManager.GetGroup(SID)
  return (g.Members);
}

并且此框架还有更多应用,例如获取域中的所有用户、检查用户帐户是否已启用、检索确定组织单元中的所有用户等等。 探索代码。

我提供了一个演示应用程序,它显示了整个 Active Directory 树。

关注点

这个框架真正棒的一点是它完全按需加载。

这意味着所有集合仅在您需要时才加载。 这很好,因为 Active Directory 数据库并不是真的很快,所以您真的不想每次想访问用户时都加载整个树,例如。

例如:假设您有一个组织单元 Users,然后在其内部有一个组织单元 Support,在 Support 内部有一个用户 TestUser。 当您获取根节点时,它不会加载 Users 组织单元。 它仅在您访问 root.OrganizationalUnits 时才加载。 然后它会加载根节点的所有子节点(包括我们的 Users 节点)。 然后,当您访问 UsersNode.OrganizationalUnits 时,它会加载 Users 组织单元节点的所有子节点(包括我们的 Support 节点)。 依此类推。

另一个真正有助于此框架的(虽然我没有时间实现它,即使我很想这样做)是向其中添加缓存,这样当您获取之前已经获取过的节点时,它将使用缓存版本。

历史

V 1.0 - AD 对象导航器已发布。

待办事项

缓存框架中的对象。

© . All rights reserved.