WindowsIdentity: Exception: System.Security.SecurityException: имя пользователя или пароль неверны
В Windows Server 2012 R2 мы хотим получить группы безопасности пользователя из Active Directory по C#-коду. Приложение является ASP.NET MVC5-проектом и размещается на IIS.
Сначала мы запрашиваем учетную запись пользователя из Active Directory UserPrincipal.FindByIdentity(...)
, Это отлично работает. Далее мы используем WindowsIdentity
класс для запроса групп безопасности из активного каталога. Мы используем класс WindowsIdentity
потому что ответ очень быстрый.
Вот код:
var lDomain = "MyDomain";
var lSamAccountName = "Simon";
using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain, lDomain))
{
// Get User Account from Active Directory
using (UserPrincipal lUserPrincipal = UserPrincipal.FindByIdentity(ctx, IdentityType.SamAccountName, lSamAccountName))
{
var lUpn = lUserPrincipal.UserPrincipalName; // get UPN
// get Security Groups of the user
using (WindowsIdentity lWindowsIdentity = new WindowsIdentity(lUpn)) // Exception: System.Security.SecurityException: The user name or password is incorrect
{
var lGroups = lWindowsIdentity.Groups;
}
}
}
Проблема: при создании WindowsIdentity
class (и передавая UPN), тогда происходит исключение:
“Upn: 'simon@MyDomain' Exception: System.Security.SecurityException: The user name or password is incorrect.
at System.Security.Principal.WindowsIdentity.KerbS4ULogon(String upn, SafeAccessTokenHandle& safeTokenHandle)
at System.Security.Principal.WindowsIdentity..ctor(String sUserPrincipalName, String type)
at System.Security.Principal.WindowsIdentity..ctor(String sUserPrincipalName)
at ...
Это любопытно, потому что запрос с UserPrincipal.FindByIdentity(...)
Был успешен. Некоторые аккаунты работают. Некоторые аккаунты не работают. Я не могу найти разницу между рабочим и не рабочим аккаунтами.
Вопрос: кто знает, что я делаю не так?
Дополнительные примечания:
- Идентификационные данные Applicationpool: LocalSystem
- В файле Web.config есть следующая запись:
<identity impersonate="false" />
Когда я запрашиваю группы по следующей альтернативе, исключение не возникает, и результат удовлетворительный. Это любопытно:
var lResult = new List<SecurityIdentifier>(); DirectorySearcher lDirectorySearcher = new DirectorySearcher(); lDirectorySearcher.Filter = string.Format(CultureInfo.InvariantCulture, "(&(objectClass=user)(distinguishedName={0}))", lUserPrincipal.DistinguishedName); // for the object lUserPrincipal, look @ code above lDirectorySearcher.SearchScope = SearchScope.Subtree; SearchResult lSearchResult = lDirectorySearcher.FindOne(); DirectoryEntry lDirectoryEntry = lSearchResult.GetDirectoryEntry(); lDirectoryEntry.RefreshCache(new string[] { "tokenGroups" }); // get groups for (int i = 0; i < lDirectoryEntry.Properties["tokenGroups"].Count; i++) { SecurityIdentifier lSid = new SecurityIdentifier((byte[])lDirectoryEntry.Properties["tokenGroups"][i], 0); lResult.Add(lSid); // Translate into NTAccount to get Domain and SAMAccountname etc... [...] }
3 ответа
Я действительно не знаю, помогает ли это, но где-то я нашел это:
- Если IIS установлен для разрешения анонимного доступа, вы можете использовать формат userPrincipleName (
username@domain
). - Если анонимный доступ НЕ включен в IIS, вам нужно использовать имя пользователя в форме
domain\username
,
Кажется странным, что для некоторых учетных записей UPN работает, а для других - нет..
Решение 1:
Используйте ADSI Edit (через MMC.exe), чтобы заполнить вручную userPrincipalName
атрибут желаемой учетной записи службы Windows.
Формат userPrincipalName
является
<username>@<fully_qualified_domain_name>
Например, для приведенных выше строк журнала ожидаемое значение UPN должно быть
goodadmin@example.com
Подождите несколько минут, пока репликация Active Directory завершится, прежде чем пытаться использовать учетные данные учетной записи службы.
Решение 2:
Убедитесь, что информация об учетной записи службы Active Directory имеет необходимые разрешения на локальном хосте BEMS в качестве локального администратора и входа в систему в качестве службы.
Убедитесь, что введенные данные учетной записи службы Active Directory действительно действительны. Например, убедитесь, что пароль введен правильно и что учетная запись не заблокирована в Active Directory.
Убедитесь, что информация учетной записи службы Active Directory имеет необходимые разрешения группы Active Directory.
RTCUniversalReadOnlyAdmins
Здесь вы можете найти, как получить группы на основе UserPrincipal
Как создать WindowsIdentity/WindowsPrincipal из имени пользователя в формате DOMAIN\user
// find all groups the user is member of (the check is recursive).
// Guid != null check is intended to remove all built-in objects that are not really AD gorups.
// the Sid.Translate method gets the DOMAIN\Group name format.
var userIsMemberOf = p.GetAuthorizationGroups().Where(o => o.Guid != null).Select(o => o.Sid.Translate(typeof(NTAccount)).ToString());
// use a HashSet to find the group the user is member of.
var groups = new HashSet<string>(userIsMemberOf), StringComparer.OrdinalIgnoreCase);
groups.IntersectWith(groupNames);