C# Active Directory服务:PrincipalContext--a的DN是什么;货柜;对象

C# Active Directory服务:PrincipalContext--a的DN是什么;货柜;对象,c#,.net-3.5,active-directory,directoryservices,C#,.net 3.5,Active Directory,Directoryservices,我目前正在尝试使用PrincipalContext类通过Active Directory服务进行身份验证。我想让我的应用程序使用密封和SSL上下文对域进行身份验证。为此,我必须使用: 具体来说,我使用的构造函数如下: PrincipalContext domainContext = new PrincipalContext( ContextType.Domain, domain, container, ContextOptions.Sealing | Con

我目前正在尝试使用PrincipalContext类通过Active Directory服务进行身份验证。我想让我的应用程序使用密封和SSL上下文对域进行身份验证。为此,我必须使用:

具体来说,我使用的构造函数如下:

PrincipalContext domainContext = new PrincipalContext(
    ContextType.Domain, 
    domain, 
    container, 
    ContextOptions.Sealing | ContextOptions.SecureSocketLayer);
MSDN提到“容器”:

存储上要用作 上下文的根。所有查询 在该根目录下执行,并且 将执行插入到该文件中 容器域和 ApplicationDirectory上下文类型, 此参数是可分辨的 容器对象的名称(DN)


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

好吧,我设法解决了这个问题:

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身份验证和查询,但这对我来说似乎很奇怪。

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


corp.contoso.com
=>
var container=“DC=corp,DC=contoso,DC=com”

您对“奇怪部分”的解释是修复20秒延迟调用的关键。谢谢我知道这是非常古老的,但我正在研究是否使用SSL进行签名,并偶然发现了这篇文章。我相信您可以在构造函数中使用
null
。当我想指定ContextOptions时,我就是这样做的。示例:
var pc=new PrincipalContext(ContextType.Domain,Environment.UserDomainName,null,ContextOptions.Sealing)@nameless:我想这就是最后一个代码块中显示的代码。(FWIW,我几乎不记得这是怎么回事,但记得当我意识到这一点时,我真的很高兴。):@Pretzel-ahhh。很高兴听到你这么说,谢谢你指出我没有完全阅读整个答案,哈哈。当我看到你的答案中通过在ValidateCredentials中指定ContextOptions来阅读的部分时,我已经停止阅读了
PrincipalContext domainContext = new PrincipalContext(ContextType.Domain,domain,
    null,ContextOptions.Negotiate | ContextOptions.SecureSocketLayer);