Pre*_*zel 20 c# directoryservices active-directory .net-3.5
我目前正在尝试使用PrincipalContext类通过Active Directory服务进行身份验证.我想让我的应用程序使用密封和SSL上下文对域进行身份验证.为了做到这一点,我必须使用PrincipalContext的以下构造函数(链接到MSDN页面):
public PrincipalContext(
ContextType contextType,
string name,
string container,
ContextOptions options
)
Run Code Online (Sandbox Code Playgroud)
具体来说,我正在使用构造函数:
PrincipalContext domainContext = new PrincipalContext(
ContextType.Domain,
domain,
container,
ContextOptions.Sealing | ContextOptions.SecureSocketLayer);
Run Code Online (Sandbox Code Playgroud)
MSDN说"容器":
商店中的容器用作上下文的根.所有查询都在此根下执行,所有插入都将在此容器中执行.对于Domain和ApplicationDirectory上下文类型,此参数是容器对象的可分辨名称(DN).
容器对象的DN是多少?如何找出容器对象是什么?我可以查询Active Directory(或LDAP)服务器吗?
Pre*_*zel 30
好吧,我设法找出了问题:
PrincipalContext domainContext = new PrincipalContext(ContextType.Domain,domain);
domainContext.ValidateCredentials(userName, password,
ContextOptions.Negotiate | ContextOptions.SecureSocketLayer);
Run Code Online (Sandbox Code Playgroud)
通过在ValidateCredentials方法中指定ContextOptions(而不是在构造函数中),这使我可以避免必须为容器对象指定DN.
更新:
虽然我应该澄清一下,经过进一步的实验,我发现从这个PrincipalContext对象派生的任何查询都是经过UN加密的.
显然,当在ValidateCredentials中设置ContextOptions时,这些选项仅用于ValidateCredentials的特定调用.但这里奇怪的地方......
所以,我想让我对AD服务器的查询也加密.示例查询:
UserPrincipal p = UserPrincipal.FindByIdentity(
domainContext, IdentityType.SamAccountName, userName);
var groups = p.GetGroups();
foreach (GroupPrincipal g in groups) { /* do something */ }
Run Code Online (Sandbox Code Playgroud)
上面的代码获取了用户所属的所有组的列表,但它以明文(未加密)发生.经过多次摆弄后,我发现DN永远不需要设置.
PrincipalContext domainContext = new PrincipalContext(ContextType.Domain,domain,
null,ContextOptions.Negotiate | ContextOptions.SecureSocketLayer);
Run Code Online (Sandbox Code Playgroud)
我发现我可以将容器对象(DN)设置为null.这很好用.将其设置为空字符串("")会导致某种未知类型的异常,因此不要认为您可以为其提供空字符串.
这是奇怪的部分.您认为在PrincipalContext中设置SecureSocketLayer选项意味着您在使用VerifyCredentials时不必显式设置它.但我发现,如果我没有在VerifyCredentials部分中设置它,则身份验证将失败,但查询(例如组中的示例)仍然是加密的.
也许我还没有完全理解AD身份验证和查询,但这对我来说似乎很奇怪.