Server 2016 AD и IIS Express не могут установить пароль пользователя, но могут создать пользователя - PullRequest
0 голосов
/ 10 октября 2019

Мне пришлось создать новую среду разработки с меньшим количеством виртуальных машин, поскольку моя IDE продолжала падать, поэтому я создал виртуальную машину с AD и IIS на одном и том же сервере.

Я использовал следующий код в моем старомсреда:

      PrincipalContext ctx = new PrincipalContext(ContextType.Domain,
                Environment.GetEnvironmentVariable("DOMAIN"),
                Environment.GetEnvironmentVariable("USER_OU"),
                Environment.GetEnvironmentVariable("SERVICE_USERNAME"),
                Environment.GetEnvironmentVariable("SERVICE_PASSWORD"));

        UserPrincipalEx usr = new UserPrincipalEx(ctx);

        usr.Name = ticket.FirstName + " " + ticket.LastName;
        usr.SamAccountName = ticket.Username;
        usr.GivenName = ticket.FirstName;
        usr.Surname = ticket.LastName;
        usr.DisplayName = ticket.FirstName + " " + ticket.Account.LastName;
        usr.UserPrincipalName = ticket.Username + "@" + Environment.GetEnvironmentVariable("DOMAIN");
        usr.Enabled = enabled;

        try
        {
            usr.Save();
            usr.SetPassword(temppwd);
            usr.ExpirePasswordNow();
        }

Я все еще могу сохранить пользователя, и он появляется в AD, однако SetPassword больше не работает:

[IIS EXPRESS] Request started: "POST" https://localhost:5001/create
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.UnauthorizedAccessException: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
   --- End of inner exception stack trace ---
   at System.DirectoryServices.DirectoryEntry.Invoke(String methodName, Object[] args)
   at System.DirectoryServices.AccountManagement.SDSUtils.SetPassword(DirectoryEntry de, String newPassword)
   at System.DirectoryServices.AccountManagement.ADStoreCtx.SetPassword(AuthenticablePrincipal p, String newPassword)
   at System.DirectoryServices.AccountManagement.PasswordInfo.SetPassword(String newPassword)
   at System.DirectoryServices.AccountManagement.AuthenticablePrincipal.SetPassword(String newPassword)

Моя учетная запись службы является администратором домена, и я получаю то же самоеошибка, если я попробую свои кредиты AD

Я устал вызывать SetPassword () перед Save (), но он не работает в той же точке.

Единственное отличие состоит в том, что у меня AD и IIS на одном сервере. Я устал от Jetbrains Rider и VS2019. Я очень близко подхожу к сроку моего проекта, и я действительно застрял.

Ни у одного из пользователей нет «Пользователь не может сменить пароль», а у новых пользователей нет опций в разделе «Параметры учетной записи».

1 Ответ

1 голос
/ 10 октября 2019

SetPassword устанавливает атрибут unicodePwd. Это имеет некоторые ограничения на то, когда оно может быть обновлено. Документация для этого гласит:

Серверы операционной системы Windows 2000 требуют, чтобы клиент имел 128-битное (или лучше) SSL / TLS-зашифрованное соединение с DC, чтобыизменить этот атрибут. В операционной системе Windows Server 2003 и более поздних версиях контроллер домена также позволяет изменять атрибут unicodePwd в соединении, защищенном 128-разрядным (или лучше) шифрованием на уровне простой аутентификации и уровня безопасности (SASL) вместо SSL / TLS.

Он должен установить безопасное соединение по умолчанию (это делает для меня), но вполне возможно, что он не может в вашей настройке по любой причине.

Вы можете передать ContextOptions объект в конструкторе вашего PrincipalContext. По умолчанию автоматически устанавливается значение ContextOptions.Negotiate | ContextOptions.Signing | ContextOptions.Sealing, которое должно быть безопасным. Но ContextOptions.Negotiate использует «либо Kerberos, либо NTLM», а ContextOptions.Signing (шифрование) зависит от Kerberos. Поэтому, возможно, он возвращается к NTLM и не может зашифровать.

Вы могли бы быть в состоянии подтвердить это, проверив следующие значения после создания учетной записи:

Console.WriteLine(ctx.Options);
Console.WriteLine(((DirectoryEntry) usr.GetUnderlyingObject()).AuthenticationType);

Значения, которые вы ищете:

Negotiate, Signing, Sealing
Secure, Signing, Sealing

Это то, что я имею, когда SetPassword работает. Но я не уверен, что он действительно изменит эти значения, если вернется к NTLM. Иногда это происходит довольно тихо.

В любом случае, если Kerberos не происходит, вы можете либо устранить это, либо попытаться подключиться через LDAPS (LDAP через SSL). Это выглядело бы примерно так:

PrincipalContext ctx = new PrincipalContext(ContextType.Domain,
    Environment.GetEnvironmentVariable("DOMAIN") + ":636",
    Environment.GetEnvironmentVariable("USER_OU"),
    ContextOptions.Negotiate | ContextOptions.SecureSocketLayer,
    Environment.GetEnvironmentVariable("SERVICE_USERNAME"),
    Environment.GetEnvironmentVariable("SERVICE_PASSWORD"));

Но это может вызвать другие проблемы, так как ваш DC должен иметь сертификат, которому вы доверяете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...