Как получить имя пользователя в Active Directory с отображаемого имени в С#?
Я хочу иметь возможность получить идентификатор пользователя пользователя в 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. Любые идеи?
Ответы
Ответ 1
Я считаю, что вы можете сделать это гораздо легче, чем с ответом Дэвида, используя встроенные функции пространства имен System.DirectoryServices.AccountManagement
(S.DS.AM).
В принципе, вы можете определить контекст домена и легко найти пользователей и/или группы в 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
действительно не является тем, что вы ищете.
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;
}
}
}
Ответ 2
UserPrincipal
имеет метод GetUnderlyingObject()
, который вернет DirectoryEntry
.
Получить 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 (имя пользователя @domain):
private string GetSAMAccountFromDirectoryEntry(DirectoryEntry entry)
{
return entry.Properties["Name"].Value;
}
И здесь исчерпывающий список всех атрибутов Active Directory. Используйте "Ldap-Display-Name" при получении значения от Properties
например Properties["Ldap-Display-Name"]
Display-Name (FirstName MI LastName) может пригодиться.