Измените имя пользователя программно при подключении к серверу Sql с использованием проверки подлинности Windows из приложения Delphi.

У меня есть сервер Sql, который использует проверку подлинности Windows.

Я хочу подключиться к серверу из приложения Delphi.

По умолчанию SQL Server примет учетные данные пользователя, запускающего процесс подключения.

Это означает, что для смены логина у меня на данный момент есть два варианта:

  1. Выйдите из системы и войдите в систему как нужный пользователь, затем запустите мое приложение

  2. Запустите программу из командной строки с помощью команды RUNAS.

Я хотел бы, чтобы пользователь предоставлял учетные данные из приложения и входил в систему как этот пользователь. Возможно ли это либо путем манипулирования ConnectionString, либо путем программного изменения пользователя текущего процесса?

Самое близкое, что я нашел, это эта запись, который говорит мне, как запустить другой процесс с определенными учетными данными. Я мог бы использовать эту технику для создания программы запуска, которая запускает процесс подключения после получения учетных данных от пользователя, но мне бы хотелось чего-то более чистого.

Я использую Delphi 2010 для этого проекта.

Спасибо


person JosephStyons    schedule 03.12.2009    source источник
comment
Он не использует имя пользователя. Он использует учетные данные безопасности процесса. К каждому запущенному процессу прикреплены учетные данные безопасности. У ScottW есть правильный ответ - вам нужно изменить учетные данные безопасности процесса/потока.   -  person    schedule 03.12.2009


Ответы (2)


Я думаю, что комбинация LogonUser и затем ImpersonateLoggedOnUser поможет вам. Это должно изменить учетную запись пользователя, для которой выполняется текущий процесс. Как упоминалось gbn, вам, вероятно, придется отключить любое активное соединение перед изменением учетных данных для входа.

person Scott W    schedule 03.12.2009
comment
вероятно, лучший ответ, чем мой. Я сосредоточился на конце БД, а не на том, что вы делаете в коде. - person gbn; 03.12.2009
comment
Олицетворение предназначено только для Current THREAD (что в данном случае является преимуществом), если вам нужно обрабатывать несколько пользователей/соединений, вы можете запускать их в отдельном потоке. - person Remko; 04.12.2009

Используя метод, предложенный Scott W, этот код работал у меня. Некоторые из них, возможно, потребуется настроить в зависимости от конкретной сетевой среды.

procedure ChangeLoggedInUser(username, password, domain: string);
var
  creds: Cardinal;
begin
  try
    if LogonUser(PChar(username)
        ,PChar(domain)
        ,PChar(password)
        ,LOGON32_LOGON_NETWORK
        ,LOGON32_PROVIDER_DEFAULT
        ,creds
      )
    then begin
      ImpersonateLoggedOnUser(creds);
    end
    else begin
      RaiseLastOSError;
    end;
  finally
    //wipe the memory for security
    FillChar(username,SizeOf(username),#0);
    FillChar(password,SizeOf(username),#0);
    FillChar(domain,SizeOf(username),#0);
  end;  //try-finally
end;

Этот код можно назвать так:

...
//at this point i am logged in as whoever is logged into the local machine
DoSomethingMundane;

//change credentials of the current thread
ChangeLoggedInUser('importantuser','secretpassword','mydomain');

//now my process will be logged in as "importantuser"
DoSomethingThatRequiresCreds;

//go back to normal
ReverToSelf;

//now my process is back to normal
DoSomethingMundane;
person JosephStyons    schedule 04.12.2009