Delphi 7 - ADOConnection не может подключиться из-за флага SQL "необходимо сменить пароль"

У меня возникла проблема, возникшая при определенных обстоятельствах в моем приложении Delphi 7.

У меня есть ADOConnection, который идет к моему серверу MS SQL с некоторым именем пользователя и парольной аутентификацией SQL. Проблема заключается в том, что вход в MS SQL был создан с флагом "Пользователь должен изменить пароль при следующем входе в систему", что делает невозможным подключение ADO Connection с сообщением об ошибке "18488 - Ошибка входа для пользователя"%.* Ls ". Причина: пароль пользователя аккаунт должен быть изменен."

Обычно в MS SQL Management Studio отображается запрос на изменение пароля, и пользователь может ввести новый пароль. Вопрос в том, что я должен сделать, чтобы принудительно изменить пароль для этого пользователя в моем приложении? Я могу поймать номер ошибки и запросить изменение логина, но что тогда? В строке подключения нет флага, который я мог бы использовать для изменения пароля / сброса на новый (например, Старый пароль и Новый пароль). Что мне тогда делать?

Кто-нибудь может помочь?

2 ответа

Решение

Когда вы перехватываете ошибку 18488, вам нужно показать свой собственный диалог "Изменить пароль" и использовать свойства строки подключения "Old Password"/"Password" с помощью SQL Native Client как ваш провайдер (т.е. Provider=SQLNCLI10 или же SQLNCLI.1).

Вот небольшой код, который я использовал для проверки этого:

procedure TForm1.Button1Click(Sender: TObject);
begin
  // 12345 is the "old password"
  ADOConnection1.ConnectionString := 'Provider=SQLOLEDB.1;Password=12345;User ID=test;Initial Catalog=test;Data Source=127.0.0.1;Persist Security Info=True;';
  try
    ADOConnection1.Open;
  except
    if Assigned(ADOConnection1.Errors) and (ADOConnection1.Errors.Count > 0) and
      (ADOConnection1.Errors.Item[0].NativeError = 18488) then
    begin
      // show your "change password" dialog... new password is 67890
      ADOConnection1.ConnectionString := 'Provider=SQLNCLI10.1;Old Password=12345;Password=67890;User ID=test;Initial Catalog=test;Data Source=127.0.0.1;Persist Security Info=True;';
      ADOConnection1.Open; // this will login and change the password

      // OPTIONAL (unless you use SQLNCLI10.1 anyway)
      // you may close the connection and re-open with your original provider and new password
      ADOConnection1.Close;
      ADOConnection1.ConnectionString := 'Provider=SQLOLEDB.1;Password=67890;User ID=test;Initial Catalog=test;Data Source=127.0.0.1;Persist Security Info=True;';
      ADOConnection1.Open;
    end
    else
      raise;          
  end;
  ShowMessage('Login OK');
end;

Мой ответ основан на этих чтениях:

Это официальный способ изменения паролей со стороны клиента, когда вы принудительно истекаете срок действия пароля и используете опцию "Пользователь должен сменить пароль при следующем входе в систему" ​​на сервере SQL.


Если проблема заключается в установке собственного клиента SQL Server на компьютере пользователя, я могу придумать еще несколько вариантов:

  1. Создайте веб-сервис (на ваших серверах), который будет отвечать за изменение пароля пользователя при наличии старых / новых паролей и возвращение статуса обратно вашему клиенту.
  2. Подключитесь как "супер пользователь" (такой как sa) и измените пароль пользователя / логина. Это означает, что вам нужно будет хранить это имя пользователя / пароль на клиентском компьютере (плохая идея, IMHO, с точки зрения безопасности, но может быть работоспособной). - не испытано
  3. НЕ создавайте логины SQL с "Пользователь должен сменить пароль при следующем входе в систему". что является моим любимым решением

Если вы счастливы, что можете перехватить это конкретное сообщение, вы можете показать свою собственную форму, объясняющую, что пароль для входа в SQL должен быть изменен, и попросить пользователя ввести новый пароль. Затем с помощью команды ALTER LOGIN измените пароль.

В целях безопасности я бы использовал опцию OLD_PASSWORD, чтобы этот пользователь знал старый пароль и, следовательно, имел возможность установить новый пароль.

Если вы не хотите, чтобы пользователь устанавливал его, то установите его самостоятельно.

Обратите внимание, что для этого у вашего пользователя должно быть установлено разрешение ALTER ANY LOGIN.

Другие вопросы по тегам