Как получить 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();
}
Другие вопросы по тегам