Как получить UPN для аутентифицированного пользователя в веб-приложении.NET, не запрашивая Active Directory
(Этот вопрос аналогичен получению UPN или электронной почты для вошедшего в систему пользователя в веб-приложении.NET, но не совсем.)
В веб-приложении.NET (C#), использующем проверку подлинности Windows, я хотел бы найти UPN зарегистрированного пользователя.
Я знаю, как это сделать, запросив Active Directory: возьмите "DOMAINNAME\userName" из HttpContext.Current.User.Identity as WindowsIdentity
; искать доменное имя под ldap://RootDSE
и найти его dnsRoot
; запрос для (&(objectCategory=person)(objectClass=user)(sAMAccountName=...userName...))
под ldap://...dnsRoot...
; получить эту запись userPrincipalName
имущество. (Более подробно в ответе /questions/29397757/active-directory-ldap-zapros-po-samaccountname-i-domenu/29397770#29397770).
Мой вопрос: можно ли найти UPN без звонка в Active Directory? Учитывая стремление Microsoft использовать UPN везде, разве UPN уже не хранится где-то в токене, который создается, когда пользователь аутентифицируется на веб-сервере?
(Поддерживающее наблюдение: если я бегу whoami /upn
в Windows 7 Wireshark не показывает никаких подключений Active Directory.)
(Если это имеет какое-либо значение: обратите внимание, что наше веб-приложение не использует олицетворение, т. Е. Наше веб-приложение не выполняется под идентификатором пользователя.)
2 ответа
Пытаться System.DirectoryServices.AccountManagement.UserPrincipal.Current
, который имеет свойство UserPrincipalName
, Конечно, это потребует запуска приложения под аутентификацией Windows.
Edit Meh, похоже, что этот API все еще выполняет поиск в каталоге.
У меня были проблемы с запросом Active Directory при использовании System.DirectoryServices.AccountManagement.UserPrincipal.Current
поэтому я прибег к использованию GetUserNameEx
с NameUserPrincipal
формат.
Эта функция получает информацию о текущем пользователе, поэтому она требует, чтобы вы выдавали себя за другого, если вы этого еще не сделали. В C# это можно сделать, импортировав функцию:
public enum EXTENDED_NAME_FORMAT
{
NameUnknown = 0,
NameFullyQualifiedDN = 1,
NameSamCompatible = 2,
NameDisplay = 3,
NameUniqueId = 6,
NameCanonical = 7,
NameUserPrincipal = 8,
NameCanonicalEx = 9,
NameServicePrincipal = 10,
NameDnsDomain = 12
}
[DllImport("secur32.dll", CharSet = CharSet.Auto)]
public static extern int GetUserNameEx(int nameFormat, StringBuilder userName, ref int userNameSize);
Тогда называя это так:
string upn = null;
StringBuilder userName = new StringBuilder(1024);
int userNameSize = userName.Capacity;
if (GetUserNameEx((int)EXTENDED_NAME_FORMAT.NameUserPrincipal, userName, ref userNameSize) != 0)
{
upn = userName.ToString();
}