我希望能够使用该用户的显示名称获取Active Directory中用户的用户标识。显示名称是从数据库中获取的,并且在该用户会话期间使用以下代码存储以获取显示名称:
using System.DirectoryServices.AccountManagement;
private string GetDisplayName()
{
// set up domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
// find currently logged in user
UserPrincipal user = UserPrincipal.Current;
return user.DisplayName;
}
这一次,我希望有一个名为GetUserIdFromDisplayName()
的方法,它返回Active Directory登录名。有什么想法吗?
答案 0 :(得分:32)
我相信通过使用System.DirectoryServices.AccountManagement
(S.DS.AM)命名空间的内置功能,您可以比使用David的答案更容易做到这一点。
基本上,您可以定义域上下文并轻松在AD中查找用户和/或组:
using System.DirectoryServices.AccountManagement;
private string GetUserIdFromDisplayName(string displayName)
{
// set up domain context
using(PrincipalContext ctx = new PrincipalContext(ContextType.Domain))
{
// find user by display name
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, displayName);
//
if (user != null)
{
return user.SamAccountName;
// or maybe you need user.UserPrincipalName;
}
else
{
return string.Empty;
}
}
}
我认为没有必要去基础的DirectoryEntry
对象,除非UserPrincipal
的所有属性都不是您正在寻找的。 p>
PS:如果按显示名称搜索不起作用(我手边没有AD来测试它) - 您也可以随时使用PrincipalSearcher
找到您的用户:
using System.DirectoryServices.AccountManagement;
private string GetUserIdFromDisplayName(string displayName)
{
// set up domain context
using(PrincipalContext ctx = new PrincipalContext(ContextType.Domain))
{
// define a "query-by-example" principal - here, we search for a UserPrincipal
// and with the display name passed in
UserPrincipal qbeUser = new UserPrincipal(ctx);
qbeUser.DisplayName = displayName;
// create your principal searcher passing in the QBE principal
PrincipalSearcher srch = new PrincipalSearcher(qbeUser);
// find match - if exists
UserPrincipal user = srch.FindOne() as UserPrincipal;
if (user != null)
{
return user.SamAccountName;
// or maybe you need user.UserPrincipalName;
}
else
{
return string.Empty;
}
}
}
答案 1 :(得分:8)
UserPrincipal
有GetUnderlyingObject()
方法会返回DirectoryEntry
。
从Principal获取DirectoryEntry:
private DirectoryEntry GetDirectoryEntryFromUserPrincipal(Principal user)
{
return (DirectoryEntry)user.GetUnderlyingObject();
}
从域名和帐户名称获取DirectoryEntry:
private DirectoryEntry GetDirectoryEntryFromDomainAndUsername(string domainName, string userName)
{
// Get the sid from the NT account name
var sid = (SecurityIdentifier) new NTAccount(domainName, accountName)
.Translate(typeof(SecurityIdentifier));
// Get the directory entry for the LDAP service account
var serviceEntry = new DirectoryEntry("LDAP://{address}", "serviceUsername", "servicePassword");
var mySearcher = new DirectorySearcher(serviceEntry)
{
Filter = string.Format("(&(ObjectSid={0}))", sid.Value)
};
return mySearcher.FindOne().GetDirectoryEntry();
}
让DirectoryEntry
使用Guid
属性获取条目Object-Guid
private Guid GetObjectGuidFromDirectoryEntry(DirectoryEntry entry)
{
// return the Guid this is the Object-Guid (ignore NativeGuid)
return entry.Guid;
}
使用目录帐户跟踪应用程序中的用户帐户:始终使用Object-Guid作为“创建对象时无法更改此值。”
如果用户更改域名,或者更常见的是更改其姓名(婚姻,合法姓名更改等),则NT和SAM帐户名称可能会更改,并且不应用于跟踪用户。
获取NT帐户名称(域\用户名):
private string GetNTAccountNameFromDirectoryEntry(DirectoryEntry entry)
{
PropertyValueCollection propertyValueCollection = entry.Properties["objectsid"];
SecurityIdentifier sid = new SecurityIdentifier((byte[]) propertyValueCollection[0], 0);
NTAccount ntAccount = (NTAccount)sid.Translate(typeof (NTAccount));
return account.ToString();
}
获取SAM帐户名称(用户名@域名):
private string GetSAMAccountFromDirectoryEntry(DirectoryEntry entry)
{
return entry.Properties["Name"].Value;
}
这是所有Active Directory属性的exhaustive list。从Properties
获取值时,请使用“Ldap-Display-Name”
例如Properties["Ldap-Display-Name"]
Display-Name(FirstName MI LastName)可能派上用场。