我目前正在尝试使用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/