【问题标题】:Active Directory Services: PrincipalContext -- What is the DN of a "container" object?Active Directory 服务:PrincipalContext——“容器”对象的 DN 是什么?
【发布时间】:2011-02-02 01:02:14
【问题描述】:

我目前正在尝试使用 PrincipalContext 类通过 Active Directory 服务进行身份验证。我想让我的应用程序使用 Sealed 和 SSL 上下文对域进行身份验证。为此,我必须使用the following constructor of PrincipalContext (link to MSDN page)

public PrincipalContext(
    ContextType contextType,
    string name,
    string container,
    ContextOptions options
)

具体来说,我是这样使用构造函数的:

PrincipalContext domainContext = new PrincipalContext(
    ContextType.Domain, 
    domain, 
    container, 
    ContextOptions.Sealing | ContextOptions.SecureSocketLayer);

MSDN 谈到“容器”:

商店中用作的容器 上下文的根。所有查询 在此根下执行,并且所有 插入到这个 容器。对于域和 ApplicationDirectory 上下文类型, 这个参数是有区别的 容器对象的名称 (DN)。

容器对象的 DN 是什么?如何找出我的容器对象是什么?我可以为此查询 Active Directory(或 LDAP)服务器吗?

【问题讨论】:

    标签: c# .net-3.5 active-directory directoryservices


    【解决方案1】:

    好吧,我设法弄清楚了这个问题:

    PrincipalContext domainContext = new PrincipalContext(ContextType.Domain,domain);
    
    domainContext.ValidateCredentials(userName, password, 
        ContextOptions.Negotiate | ContextOptions.SecureSocketLayer);
    

    通过在 ValidateCredentials 方法中(而不是在构造函数中)指定 ContextOptions,我可以避免为容器对象指定 DN。

    更新:

    虽然我应该澄清一下,经过进一步的实验,我发现从这个 PrincipalContext 对象派生的任何查询都是未经加密的。

    显然,当在 ValidateCredentials 中设置 ContextOptions 时,这些选项仅用于 ValidateCredentials 的特定调用。但这就是奇怪的地方......

    所以,我希望对 AD 服务器的查询也进行加密。示例查询:

    UserPrincipal p = UserPrincipal.FindByIdentity(
        domainContext, IdentityType.SamAccountName, userName);
    var groups = p.GetGroups();
    foreach (GroupPrincipal g in groups) { /* do something */ }
    

    上面的代码获取用户所属的所有组的列表,但它以明文(未加密)发生。所以经过一番折腾,我发现DN永远不需要设置。

    PrincipalContext domainContext = new PrincipalContext(ContextType.Domain,domain,
        null,ContextOptions.Negotiate | ContextOptions.SecureSocketLayer);
    

    我发现我可以将容器对象 (DN) 设置为 null。这很好用。将其设置为空字符串 ("") 会导致某种未知类型的异常,所以不要以为可以给它一个空字符串。

    这是奇怪的部分。您会认为在 PrincipalContext 中设置 SecureSocketLayer 选项意味着您在使用 VerifyCredentials 时不必显式设置它。但是我发现如果我没有在 VerifyCredentials 部分设置它,身份验证将失败,但查询(如对组的示例)仍然是加密的。

    也许我还没有完全理解 AD 身份验证和查询,但这对我来说似乎很奇怪。

    【讨论】:

    • 您对“奇怪的部分”的解释是解决调用 ValidateCredentials 时延迟 20 秒的关键。谢谢!
    • 我知道这已经很老了,但我正在研究是否使用 SSL over Signing 并遇到了这篇文章。我相信你可以在构造函数中使用null。当我想指定 ContextOptions 时,我就是这样做的。示例:var pc = new PrincipalContext(ContextType.Domain, Environment.UserDomainName, null, ContextOptions.Sealing);
    • @nameless:我认为这就是代码在最后一个代码块中显示的内容。 (FWIW,我几乎不记得这是怎么回事,但记得当我弄清楚时真的很高兴。):)
    • @Pretzel Ahhhhhh。很高兴听到并感谢您指出我未能完全阅读整个答案,哈哈。当我读到您的答案部分时,我已经停止阅读 通过在 ValidateCredentials 中指定 ContextOptions
    【解决方案2】:

    容器可以设置为域的DC部分。

    corp.contoso.com => var container = "DC=corp, DC=contoso, DC=com"

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-02
      • 2016-12-05
      相关资源
      最近更新 更多