Ответ 1
Я как раз собирался добавить свой собственный вопрос в StackOverflow с моим решением, чтобы помочь другим с этой проблемой, когда я увидел ваш существующий вопрос. Похоже, это будет очень распространено, но информация о том, как это сделать, распространяется только между несколькими источниками и трудно отслеживать. Там не только один полный ресурс, поэтому, надеюсь, это поможет вам и другим.
Лучший способ сделать это - использовать расширение UserPrincipal. В основном, вы подклассифицируете UserPrincipal
из System.DirectoryServices.AccountManagement
и добавьте свои собственные дополнительные свойства. Это активируется с помощью методов ExtensionGet
и ExtensionSet
(несколько магических).
[DirectoryRdnPrefix("CN")]
[DirectoryObjectClass("user")]
public class UserPrincipalExtended : UserPrincipal
{
public UserPrincipalExtended(PrincipalContext context) : base(context)
{
}
public UserPrincipalExtended(PrincipalContext context, string samAccountName, string password, bool enabled)
: base(context, samAccountName, password, enabled)
{
}
[DirectoryProperty("title")]
public string Title
{
get
{
if (ExtensionGet("title").Length != 1)
return null;
return (string)ExtensionGet("title")[0];
}
set
{
ExtensionSet( "title", value );
}
}
[DirectoryProperty("department")]
public string Department
{
get
{
if (ExtensionGet("department").Length != 1)
return null;
return (string)ExtensionGet("department")[0];
}
set
{
ExtensionSet("department", value);
}
}
public static new UserPrincipalExtended FindByIdentity(PrincipalContext context, string identityValue)
{
return (UserPrincipalExtended)FindByIdentityWithType(context, typeof(UserPrincipalExtended), identityValue);
}
public static new UserPrincipalExtended FindByIdentity(PrincipalContext context, IdentityType identityType, string identityValue)
{
return (UserPrincipalExtended)FindByIdentityWithType(context, typeof(UserPrincipalExtended), identityType, identityValue);
}
}
Два атрибута класса должны быть настроены для вашего экземпляра AD. Значение для DirectoryRdnPrefix
должно быть RDN (относительное различающееся имя) в AD, а значение для DirectoryObjectClass
должно быть именем типа объекта каталога в AD для класса userObject. Для типичной настройки доменных служб AD они должны использоваться как в коде, представленном выше, но для настройки LDS они могут быть разными. Я добавил два новых свойства, которые использует моя организация: "title" и "department". Из этого вы можете получить представление о том, как добавить любое другое свойство, которое вам нравится: в основном вы просто создаете свойство, используя шаблон, который я здесь предоставил. Свойству можно назвать все, что угодно, но строковое значение, переданное в DirectoryProperty
и внутри блока кода, должно совпадать с именем свойства из AD. Используя это, вы можете использовать PrincipalContext
с вашим подклассом вместо UserPrincipal
, чтобы вернуть пользовательский объект со свойствами, которые вам нужно добавить.
UserPrincipalExtended user = UserPrincipalExtended.FindByIdentity(
new PrincipalContext(ContextType.Domain), User.Identity.Name);
И получите доступ к свойству, как и любой другой, в экземпляре UserPrincipal
:
// User title
user.Title
Если вы не знакомы с System.DirectoryServices.AccountManagement.UserPrincipal
, есть несколько свойств пользователя, испеченных в: GivenName
, Surname
, DisplayName
и т.д. В частности, в ваших обстоятельствах, поскольку вы упомянули телефон и электронную почту конкретно, VoiceTelephoneNumber
и EmailAddress
. Полный список можно увидеть в Документах MSDN. Если вам нужна только встроенная информация, вам не нужно расширять UserPrincipal
, как я показал выше. Вы просто сделали бы:
UserPrincipal user = UserPrincipal.FindByIdentity(
new PrincipalContext(ContextType.Domain), User.Identity.Name);
Но, в 9 раз из 10, встроенных модулей будет недостаточно, так что хорошо знать, как легко получить остальное.
Наконец, я не хотел добавлять строки @using
к любому виду, которое использует это, поэтому я пошел дальше и добавил пространства имен в папку Views
web.config. Эта часть важна, ее нужно добавить в папку Views
web.config, а не проект (и каждую отдельную область Views
для каждого региона), если вы используете области.
<system.web.webPages.razor>
...
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
...
<add namespace="System.DirectoryServices.AccountManagement" />
<add namespace="Namespace.For.Your.Extension" />
</namespaces>
</pages>
</system.web.webPages.razor>