如何在远程 LDAP 服务器上的特定 OU 中搜索用户
本文关键字:OU 用户 搜索 服务器 LDAP | 更新日期: 2023-09-27 18:30:21
我想使用 .NET 3.5 中引入的 AccountManagement
命名空间来查找用户并设置其密码。 但是,ADLDS 服务器不是我们公司域的一部分,所以我正在使用 ContextType.Machine
. 当我搜索用户时,它从未找到(我怀疑它在错误的容器中搜索,但根据使用ContextType.Machine
时的文档,您无法指定容器)。
using (var context = new PrincipalContext(ContextType.Machine, "test-server", null, "username", "password")) {
using (var u = UserPrincipal.FindByIdentity(context, "SuperAdmin")) {
//u is always null. :(
}
}
但是,我知道我可以使用普通的 ol' DirectoryEntry
找到用户:
using (var de = new DirectoryEntry("LDAP://test-server:389/CN=SuperAdmin,CN=SuperUsers,OU=test-server,DC=foo,DC=bar,DC=com", "username", "password", AuthenticationTypes.Secure)) {
//The user is found, but SetPassword fails with "The directory property cannot be found in the cache"
de.Invoke("SetPassword", new object[] { "foobar" });
}
最后要指出的是,我可以使用 ADSI 编辑来更改具有这些相同凭据的密码。 是否可以使用较新的目录对象来执行此搜索?
这确实是一个老问题,但就在最近我不得不从事一个类似的项目......如果有人遇到同样的问题,我会发布答案。
使用类找不到user
UserPrincipal
原因是,正如您提到的,您正在使用ContextType.Machine
进行搜索。但是DirectEntry
类中,您只是在执行一个简单的LDAP://
查询。
这是我的解决方案。
我将服务器信息存储在.config
文件中。
...
//Server name and port
<add key ="ADLDS_Server" value="Servername:port"/>
//Note* depending on structure container will be different for everybody
<add key ="ADLDS_Container" value="CN=Some Value, DC=some value,DC=value"/>
...
然后ADLDSUtility
我创建了返回PrincipalContext
对象的类。
...
using System.DirectoryServices.AccountManagement
...
public class ADLDSUtility
{
public static ContextOptions ContextOptions = ContextOptions.SecureSocketLayer | ContextOptions.Negotiate;
public static PrincipalContext Principal
{
get
{
return new PrincipalContext(
ContextType.ApplicationDirectory,
ConfigurationManager.AppSettings["ADLDS_Server"],
ConfigurationManager.AppSettings["ADLDS_Container"],
//you can specify username and password if need to
ContextOptions);
}
}
从那里,我写了一个接受(用户名,当前密码和新密码)作为参数的method
。
public void ChangePassword(string userName, string currentPassword, string newPassword)
{
using (PrincipalContext ctx = ADLDSUtility.Principal)
{
using (UserPrincipal principal = new UserPrincipal(ctx))
{
using (var searchUser = UserPrincipal.FindByIdentity(ctx, IdentityType.UserPrincipalName, userName))
{
if (searchUser != null)
{
searchUser.ChangePassword(currentPassword, newPassword);
// searchUser.SetPassword(newPassword);
if (String.IsNullOrEmpty(searchUser.Guid.ToString()))
{
throw new Exception("Could not change password");
}
}
}
}
}
}
在此示例中,我按UserPrincipalName
搜索用户。但我们不仅限于此。我们还可以按IdentityType.Guid
等搜索用户。
现在searchUser
有两种涉及密码的方法。我提供了他们两个。
//requires current and new password
searchUser.ChangePassword(currentPassword, newPassword);
//setting a password. Only requires new password.
searchUser.SetPassword(newPassword);
请注意,最好使用 SSL 来设置或更改密码。