我根据以下代码构建了一个类:Everything in Active Directory via C#.NET 3.5 (Using System.DirectoryServices.AccountManagement) - CodeProject。它在我的场景中完美运行。但是,最近,我们重新构建了域设置,这次涉及到全局编录以及活动目录用户的复杂分发。这是一个粗略的图表:
现在,我一直在努力坚持使用PrincipleContext API并满足要求,但似乎我错过了一些东西。要求很简单:
AD用户将能够验证自己的凭据:这样就完成了:
public string AuthenticateUsingPrincipalcontext(string strDomain, string strUserName, string strPassword)
{
string strDistinguishedName;
var strPath = string.Empty;
PrincipalContext ctx = null;
var domainArr = strDomain.Split('.');
strPath = domainArr.Aggregate(strPath, (current, strDc) => current + $"DC={strDc},");
if (strPath.EndsWith(","))
{
strPath = strPath.Substring(0, strPath.Length - 1);
}
try
{
ctx = new PrincipalContext(ContextType.Domain, strDomain + ":3268", strPath, ContextOptions.Negotiate | ContextOptions.Signing | ContextOptions.Sealing, strUserName, strPassword);
var bValid = ctx.ValidateCredentials(strUserName, strPassword);
// Additional check to search user in directory.
if (bValid)
{
var prUsr = new UserPrincipal(ctx) {SamAccountName = strUserName};
var searchUser = new PrincipalSearcher(prUsr);
var foundUsr = searchUser.FindOne() as UserPrincipal;
if (foundUsr != null)
{
strDistinguishedName = foundUsr.DistinguishedName;
}
else
{
throw new AuthenticationException("Please enter valid UserName/Password.");
}
}
else
{
throw new AuthenticationException("Please enter valid UserName/Password.");
}
}
catch (Exception ex)
{
throw new AuthenticationException("Authentication Error in PrincipalContext. Message: " + ex.Message);
}
finally
{
ctx?.Dispose();
}
return strDistinguishedName;
}
请注意,我在创建主要上下文时会将":3268"
附加到域名。这将强制实施全球目录服务。但是,如果没有全局目录(非森林),它仍然有效。
AD用户可以更改密码:我假设我也可以这样做。
需要使用技术用户重置AD用户的密码:这是问题的开始。如果我使用位于 eu.company.com 中的技术用户信息来烹饪PrincipleContext(并且可以看到所有控制器上的所有用户),我就不能用它来重置用户的密码,比如说, me.company.com 或 company-abc.com