我有一个ASP .NET Web应用程序,需要对Active Directory连接中的用户列表进行身份验证和检索。问题是运行Web服务器的计算机是工作组的一部分(不是我正在使用的域)。我可以通过输入域名来验证AD,但检索用户列表失败。
我的问题是,我是否在尝试从域外获取AD用户时出错?如果是这样,我该怎么做才能纠正这个问题?我的代码片段如下:
public bool IsAuthenticated(string username, string pwd)
{
try
{
validUser = adContext.ValidateCredentials(username, pwd, ContextOptions.Negotiate);
}
catch (Exception ex)
{
Logging.Instance.Log(Logging.Levels.Error, "Error authenticating user: " + username + " : " + ex.Message.ToString());
}
return validUser;
}
public List<DirectoryEntry> GetAllUsers()
{
try
{
userADlist = new List<DirectoryEntry>();
Logging.Instance.Log(Logging.Levels.Message, "Finding all users for: "+adContext.ConnectedServer + " " + adContext.Container);
using (PrincipalSearcher searcher = new PrincipalSearcher(new UserPrincipal(adContext)))
{
foreach (Principal result in searcher.FindAll())
{
userADlist.Add(result.GetUnderlyingObject() as DirectoryEntry);
}
}
}
catch (Exception)
{
throw;
}
return userADlist;
}
答案 0 :(得分:2)
您的代码未显示创建adContext
的位置。我只能怀疑:
在工作代码(IsAuthenticated
)中,您只需检查给定的凭据(用户+ pw)是否正确。
但如果你打电话给GetAllUsers
这些凭证不会“神奇地”重复使用,那么你对外国AD的绑定就会失败。
您可以使用PrincipalContext
的构造函数来获取用户+ pw。
(https://msdn.microsoft.com/en-us/library/bb341016.aspx)
另请看一下:
How does PrincipalContext login to domain server
Validate users of Remote Active Directory in C#
connect active directory using c#
但是,正如评论所暗示的那样:使用明文密码不是一个好主意。
答案 1 :(得分:0)
感谢您的评论,我完全理解明文密码的风险。
我无法使用建议的方法使用用户名和密码绑定到PrincipalContext,因为我对将其放入配置文件或硬编码时犹豫不决。
我使用的解决方法是在非域服务器上添加域用户帐户作为管理员,然后将其用作我的Web应用程序的应用程序池标识。这样,IIS本身就使用帐户凭据对AD服务器进行身份验证,并且我正确地获得了用户列表。
谢谢你的帮助。 Rishi
答案 2 :(得分:0)
Rainer Schaack就在这里。调用IsAuthenticated
时,GetAllUsers()
函数的凭据不会用于绑定到AD。其中一个解决方案是使用用户名和密码绑定到PrincipalContext
。将凭证放入配置或对其进行硬编码存在风险。我想澄清一下,尽管使用上面的代码,这些凭据不会以明文形式传递到/来自不同域中的AD。
验证上述凭据的行是:
validUser = adContext.ValidateCredentials(username, pwd, ContextOptions.Negotiate);
ContextOptions.Negotiate
在这里很重要。文档here和here说明Negotiate
选项使用Kerberos或NTLM。调查时,这两个都不会使用明文传递凭据。
也许在发布时,事实并非如此。我没有深挖那个深刻的东西。对于那些实现类似于此前进的解决方案的人来说,理解这一点很重要。