我目前正在尝试使用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说到“容器”:



容器对象的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部分中进行设置,则身份验证将失败,但是查询(例如在对Groups的示例中)仍会加密。

也许我只是还不完全了解AD身份验证和查询,但这对我来说似乎是奇怪的行为。

关于c# - Active Directory服务: PrincipalContext — What is the DN of a “container” object?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2538064/

10-13 03:17