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);
Другие вопросы по тегам