[英]With access to Active Directory, can I get an object GUID for a user from an username/email address alone?
Background背景
I've been experimenting with active directory access in C# to find out how to connect/validate credentials in various ways.我一直在尝试 C# 中的活动目录访问,以了解如何以各种方式连接/验证凭据。 At the bottom of this answer I've included some code snippets to give an idea of what I've done, maybe this can be built upon to fulfill my aim.
在这个答案的底部,我包含了一些代码片段,以了解我所做的事情,也许可以以此为基础来实现我的目标。
Main Aim主要目标
If I have valid credentials for connecting to an Active Directory, can I take an string representing a username/email address (assuming it exists in the userPrincipalName
or similar field), and get back the objectGUID
?如果我有连接到 Active Directory 的有效凭据,我可以获取代表用户名/电子邮件地址的字符串(假设它存在于
userPrincipalName
或类似字段中),然后取回objectGUID
吗?
Or do I need to take other things into account like: the permissions those credentials have to search other users;或者我是否需要考虑其他事情,例如:这些凭据搜索其他用户的权限; knowledge of the structure of different ADs;
了解不同广告的结构; if
userPrincipalName
is the correct field to search?如果
userPrincipalName
是正确的搜索字段?
Code Snippets (experimental beginnings, not fully functional for my aim)代码片段(实验开始,不完全符合我的目标)
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();
You're on the right track with DirectorySeacher
.您在
DirectorySeacher
的正确轨道上。 You just need a proper query, and a few other tweaks.您只需要一个适当的查询,以及一些其他的调整。
Modify the Filter
so you find what you're looking for.修改
Filter
,以便您找到所需的内容。
a.一个。 If you have the email address:
如果您有 email 地址:
(&(objectClass=user)(objectClass=person)(mail=email@example.com))
(&(objectClass=user)(objectClass=person)(proxyAddresses=smtp:email@example.com))
(this will match against secondary email addresses too)(&(objectClass=user)(objectClass=person)(proxyAddresses=smtp:email@example.com))
(这也将匹配辅助 email 地址) b.湾。 If you have a username, it depends which username you have.
如果您有用户名,则取决于您拥有的用户名。
(&(objectClass=user)(objectClass=person)(userPrincipalName=username@example.com))
(&(objectClass=user)(objectClass=person)(userPrincipalName=username@example.com))
(&(objectClass=user)(objectClass=person)(sAMAccountName=myusername))
(&(objectClass=user)(objectClass=person)(sAMAccountName=myusername))
Use DirectorySeacher.PropertiesToLoad
.使用
DirectorySeacher.PropertiesToLoad
。 If you don't, it will retrieve every attribute that has a value , which is just wasted network traffic.如果不这样做,它将检索具有 value 的每个属性,这只是浪费的网络流量。
You don't need to dispose the DirectorySearcher
, but you do need to dispose resultCollection
since the documentation says you can end up with a memory leak if you leave it up to garbage collection.您不需要处置
DirectorySearcher
,但您确实需要处置resultCollection
,因为文档说如果您将其留给垃圾收集,您最终可能会出现 memory 泄漏。
So, assuming you have the userPrincipalName
, you would have something like this:所以,假设你有
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
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.