通过访问 Active Directory,我能否仅从 username/email 地址获取用户的对象 GUID?
With access to Active Directory, can I get an object GUID for a user from an username/email address alone?
背景
我一直在尝试在 C# 中访问活动目录,以了解如何以各种方式 connect/validate 凭据。在此答案的底部,我包含了一些代码片段以了解我所做的事情,也许可以以此为基础来实现我的目标。
主要目标
如果我有连接到 Active Directory 的有效凭据,我可以使用一个表示 username/email 地址的字符串(假设它存在于 userPrincipalName
或类似字段中),然后取回objectGUID
?
或者我是否需要考虑其他因素,例如:这些凭据必须具有的搜索其他用户的权限;了解不同广告的结构;如果 userPrincipalName
是要搜索的正确字段?
代码片段(实验性的开始,对我的目标来说功能不全)
var credentials = new NetworkCredential(username, password, hostname);
var serverId = new LdapDirectoryIdentifier(hostname);
var connection = new LdapConnection(serverId, credentials);
try
{
connection.Bind();
}
catch (Exception e)
{
//error
Console.WriteLine(e);
connection.Dispose();
return;
}
//success
var dirEntry = new DirectoryEntry(string.Format("LDAP://{0}/{1}", hostname, baseDn), username, password);
var searcher = new DirectorySearcher(dirEntry)
{
Filter = "(&(&(objectClass=user)(objectClass=person)))"
};
var resultCollection = searcher.FindAll();
searcher.Dispose();
您 DirectorySeacher
的方向是正确的。您只需要一个正确的查询,以及一些其他的调整。
修改 Filter
以便找到您要查找的内容。
一个。如果您有电子邮件地址:
(&(objectClass=user)(objectClass=person)(mail=email@example.com))
- 或者,
(&(objectClass=user)(objectClass=person)(proxyAddresses=smtp:email@example.com))
(这也将匹配辅助电子邮件地址)
b。如果您有用户名,则取决于您拥有的用户名。
- 用户主体名称:
(&(objectClass=user)(objectClass=person)(userPrincipalName=username@example.com))
- 通常称为 "username",其格式通常类似于 DOMAIN\username:
(&(objectClass=user)(objectClass=person)(sAMAccountName=myusername))
使用DirectorySeacher.PropertiesToLoad
。如果不这样做,它将检索每个具有值的属性,这只是浪费网络流量。
您不需要处理 DirectorySearcher
,但您确实需要处理 resultCollection
,因为 the documentation 表示您最终可能会发生内存泄漏如果你把它留给垃圾收集。
所以,假设你有 userPrincipalName
,你会得到这样的东西:
var userToLookFor = "username@example.com";
var dirEntry = new DirectoryEntry(string.Format("LDAP://{0}/{1}", hostname, baseDn), username, password);
var searcher = new DirectorySearcher(dirEntry)
{
Filter = $"(&(objectClass=user)(objectClass=person)(userPrincipalName={userToLookFor}))",
SizeLimit = 1 //we're only looking for one account
};
searcher.PropertiesToLoad.Add("objectGuid");
using (var resultCollection = searcher.FindAll())
{
if (resultCollection.Count == 1)
{
var userGuid = new Guid((byte[]) resultCollection[0].Properties["objectGuid"][0]);
}
else
{
//the account was not found - do something else
}
}
背景
我一直在尝试在 C# 中访问活动目录,以了解如何以各种方式 connect/validate 凭据。在此答案的底部,我包含了一些代码片段以了解我所做的事情,也许可以以此为基础来实现我的目标。
主要目标
如果我有连接到 Active Directory 的有效凭据,我可以使用一个表示 username/email 地址的字符串(假设它存在于 userPrincipalName
或类似字段中),然后取回objectGUID
?
或者我是否需要考虑其他因素,例如:这些凭据必须具有的搜索其他用户的权限;了解不同广告的结构;如果 userPrincipalName
是要搜索的正确字段?
代码片段(实验性的开始,对我的目标来说功能不全)
var credentials = new NetworkCredential(username, password, hostname);
var serverId = new LdapDirectoryIdentifier(hostname);
var connection = new LdapConnection(serverId, credentials);
try
{
connection.Bind();
}
catch (Exception e)
{
//error
Console.WriteLine(e);
connection.Dispose();
return;
}
//success
var dirEntry = new DirectoryEntry(string.Format("LDAP://{0}/{1}", hostname, baseDn), username, password);
var searcher = new DirectorySearcher(dirEntry)
{
Filter = "(&(&(objectClass=user)(objectClass=person)))"
};
var resultCollection = searcher.FindAll();
searcher.Dispose();
您 DirectorySeacher
的方向是正确的。您只需要一个正确的查询,以及一些其他的调整。
修改
Filter
以便找到您要查找的内容。一个。如果您有电子邮件地址:
(&(objectClass=user)(objectClass=person)(mail=email@example.com))
- 或者,
(&(objectClass=user)(objectClass=person)(proxyAddresses=smtp:email@example.com))
(这也将匹配辅助电子邮件地址)
b。如果您有用户名,则取决于您拥有的用户名。
- 用户主体名称:
(&(objectClass=user)(objectClass=person)(userPrincipalName=username@example.com))
- 通常称为 "username",其格式通常类似于 DOMAIN\username:
(&(objectClass=user)(objectClass=person)(sAMAccountName=myusername))
使用
DirectorySeacher.PropertiesToLoad
。如果不这样做,它将检索每个具有值的属性,这只是浪费网络流量。您不需要处理
DirectorySearcher
,但您确实需要处理resultCollection
,因为 the documentation 表示您最终可能会发生内存泄漏如果你把它留给垃圾收集。
所以,假设你有 userPrincipalName
,你会得到这样的东西:
var userToLookFor = "username@example.com";
var dirEntry = new DirectoryEntry(string.Format("LDAP://{0}/{1}", hostname, baseDn), username, password);
var searcher = new DirectorySearcher(dirEntry)
{
Filter = $"(&(objectClass=user)(objectClass=person)(userPrincipalName={userToLookFor}))",
SizeLimit = 1 //we're only looking for one account
};
searcher.PropertiesToLoad.Add("objectGuid");
using (var resultCollection = searcher.FindAll())
{
if (resultCollection.Count == 1)
{
var userGuid = new Guid((byte[]) resultCollection[0].Properties["objectGuid"][0]);
}
else
{
//the account was not found - do something else
}
}