Как выполнить клиентскую проверку смены пароля в Active Directory - PullRequest
2 голосов
/ 19 марта 2019

Моя цель проста: предварительно проверить новый пароль на стороне клиента (Javascript), так как начальная проверка пароля соответствует политике паролей домена / домена, чтобы не тратить ресурсы сервера на отклонение неверных паролей и быстрее реагировать на запросы пользователей.

Вопрос: Как я могу получить политику паролей пользователей из Active Directory?

Особенно мне нужно знать пароль «формат», длину пароля, прописные и специальные символы.и т. д. окончательная проверка будет, конечно, самой Active Directory.Но сначала я хочу использовать Javascript для оптимизации производительности, и я почти уверен, что смогу управлять Javascript, если смогу просто получить требования к формату пароля для конкретного пользователя / OU на стороне C # / ASP.Net.

В настоящее время я застрял, пытаясь найти ЧТО текущая политика паролей для пользователя.Да, пользователь Alice может использовать политику домена паролей, но Bob может иметь другую политику паролей в своем подразделении.

Этот веб-сайт будет установлен в учреждении с тысячами пользователей;мы хотим свести к минимуму взаимную проверку Active Directory.Кроме того, наличие этого в Javascript может в конечном итоге помочь в соответствии со специальной публикацией NIST 800-63 , которая среди прочего требует быстрой обратной связи с пользователями по поводу относительной надежности пароля.На данный момент я должен быть в состоянии заставить код работать в Windows 2008, 2008 R2 и 2012.

В настоящее время я могу изменить пароль в C #, и я могу получить ошибку, но это всеили ничего, и не полезно для проверки на стороне клиента.

public static PasswordChangeResultsDTO ChangeUserPassword(PasswordChangeRequestDTO request)
{
    try
    {
        bool isPasswordChanged = false;
        SearchResult result = LdapHelper.GetUser(request.Username, request.OldPassword);

        if (result != null)
        {
            using (DirectoryEntry userEntry = result.GetDirectoryEntry())
            {
                userEntry.Invoke("ChangePassword", new object[] {request.OldPassword, request.NewPassword});
                userEntry.CommitChanges();
                isPasswordChanged = true;
            }
        }

        return new PasswordChangeResultsDTO {PasswordChanged = isPasswordChanged};
    }
    catch (COMException comException)
    {
        LoggingHelper.Instance.WriteException(comException);
        string message = comException.ErrorCode == -2147022651
                             ? "The password does not meet the password policy requirements"
                             : comException.Message;
        return new PasswordChangeResultsDTO {PasswordChanged = false, Message = message};
    }
    catch (TargetInvocationException targetInvocationException)
    {
        LoggingHelper.Instance.WriteException(targetInvocationException);
        string message;
        if (targetInvocationException.InnerException != null)
        {
            var comException = targetInvocationException.InnerException as COMException;
            if (comException != null)
            {
                message = comException.ErrorCode == -2147022651
                          ? "The password does not meet the password policy requirements"
                          : comException.Message;
            }
            else
            {
                message = targetInvocationException.InnerException.Message;
            }
        }
        else
        {
            message = targetInvocationException.Message;
        }

        return new PasswordChangeResultsDTO {PasswordChanged = false, Message = message};
    }
    catch (Exception ex)
    {
        string msgError = (null != ex.InnerException) ? ex.InnerException.Message : ex.Message;
        string msgSource = (null != ex.InnerException) ? ex.InnerException.Source : ex.Source;
        string msgStackTrace = (null != ex.InnerException) ? ex.InnerException.StackTrace : ex.StackTrace;
        string msgOutput = String.Format(CultureInfo.InvariantCulture,
                                             "Exception in {3} MSG[{0}] SOURCE[{1}] STACK[{2}]",
                                         msgError, msgSource, msgStackTrace, MethodBase.GetCurrentMethod().Name);

        LoggingHelper.Instance.Fatal(msgOutput);
        throw;
    }
}

1 Ответ

1 голос
/ 20 марта 2019

Найти эту информацию на уровне домена легко. Выяснить, переопределены ли какие-либо групповые политики, сложно по умолчанию.

На уровне домена есть атрибуты в самом домене, которые управляют политикой паролей по умолчанию для домена. Вы можете привязать к самому домену (т.е. LDAP://domain.com) и прочитать эти атрибуты:

  • minPwdLength: минимальная длина символа
  • pwdHistoryLength: количество старых паролей, которые нельзя использовать повторно.
  • pwdProperties: Это битовый флаг, который может означать различные вещи, о которых вы можете прочитать в разделе «PasswordProperties» здесь . Вероятно, для него задано значение 1 (DOMAIN_PASSWORD_COMPLEX), что означает, что пароль должен содержать как минимум два символа: либо заглавные, строчные, либо цифры.

Если вы хотите прочитать групповые политики, применимые к подразделению пользователя, то, похоже, нет библиотек .NET, которые могли бы сделать это. Вы должны прибегнуть к использованию неуправляемого кода. Вот пример здесь , который использует интерфейс IGPMDomain из C #, но вам придется адаптировать его, чтобы найти объект групповой политики для нужного подразделения.

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