Как получить текущего зарегистрированного пользователя, включая домен в Delphi 2009? - PullRequest
1 голос
/ 26 ноября 2009

Мне нужно, чтобы текущий вошел в систему на имя пользователя? Мне нужно, чтобы это работало правильно, когда я вызываю код из ASP.NET, который работает в режиме аутентификации Windows. то есть, я не хочу, чтобы пользователь ASPNET был в этих обстоятельствах, а выдавал себя за пользователя. Это связано с моим ранее вопросом . Все, что я пробую, возвращает ASPNET .

Ответы [ 3 ]

3 голосов
/ 26 ноября 2009

В другом своем вопросе вы написали, что настроили ASP.NET для использования проверки подлинности Windows с олицетворением:

 <system.web>
    ...
    <authentication mode="Windows"/>
    <identity impersonate="true"/>
    ...
 </system.web>

Показывает ли приложение ASP.NET правильные учетные данные (пользователь и домен)?

Вы вызываете функцию Delphi, используя правильный контекст идентификации, как

WindowsIdentity winId = (WindowsIdentity)HttpContext.Current.User.Identity;
try
{
    ctx = winId.Impersonate();
    // call Delphi function, passing the identity context
}
catch
{
}
finally
{
    if (ctx != null)
        ctx.Undo();
}

Обновление:

Если COM-объект вызывается из кода для страницы веб-формы, вы можете попытаться установить для свойства ASPCOMPAT страницы веб-формы значение true.

См .:

Тег «удостоверение» гарантирует, что поток, выполняющий запрос (MTA нить) будет выдавать себя за свою безопасность контекст для пользователя, указанного в тег, но наш STA COM-объект в итоге был создан по умолчанию Нить STA, которая не была олицетворена, заставляя его получить контекст безопасности процесса (который был IUSR_XXX - наименее мощный пользователь из всех).

1 голос
/ 26 ноября 2009

Это часть кода моего LoadProfile инструмента, он хорошо работает в Delphi 2010:

const
  UNLEN = 256; // Maximum user name length

var
  TokenHandle: THandle; // Handle to the Processes' Acces Token
  cbTokenInfo: DWORD; // Size of TokenInfo in Bytes
  pTokenUser: PTOKEN_USER; // Pointer to a TOKEN_USER record

  cchName: DWORD; // Count of characters (length) of the Username array
  cchDomain: DWORD; // Count of characters (length) of the Domainname array
  peUse: DWORD; // Account type for LookupAccountSid

  UserName: array[0..UNLEN] of Char; // Holds the Username
  DomainName: array[0..UNLEN] of Char; // Holds the Domainname
  ComputerName: array[0..UNLEN] of Char; // Hold the Computername


    // Open the Current Process' Token
    OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY or
      TOKEN_IMPERSONATE or TOKEN_DUPLICATE, TokenHandle);

    // Check if we have a valid handle
    if TokenHandle = 0 then
      Exit; 

    { We will use GetTokenInformation to get the user's SID, the first call
      to GetTokenInformation is used to determine how much memory we need to
      allocate }
    GetTokenInformation(TokenHandle, TokenUser, nil, 0, cbTokenInfo);
    // as documented the call should fail with ERROR_INSUFFICIENT_BUFFER
    if (GetLastError() <> ERROR_INSUFFICIENT_BUFFER) then
      Exit;

    // Allocate Memory
    pTokenUser :=  HeapAlloc(GetProcessHeap(), 0, cbTokenInfo);
    if (pTokenUser = nil) then
       Exit;

    // Retrieve the user information from the token.
    if ( not GetTokenInformation(TokenHandle, TokenUser, pTokenUser,
      cbTokenInfo, cbTokenInfo)) then
       Exit;

    cchName := Length(UserName);
    cchDomain := Length(DomainName);
    peUse:= SidTypeUser;


    // Use the SID to find User and Domain Name
    Write('LookupAccountSid... ');
    if not LookupAccountSid(nil, pTokenUser^.User.Sid, UserName, cchName,
      DomainName, cchDomain, peUse) then
      Exit;

    // Cleanup
    if (pTokenUser <> nil) then
      HeapFree(GetProcessHeap(), 0, pTokenUser);

    WriteLn('CloseHandle... OK');
    CloseHandle(TokenHandle);
1 голос
/ 26 ноября 2009

Возможно, ваш IADsWinNTSystemInfo подход (из связанного предыдущего вопроса) возвращает информацию об учетной записи текущего процесса, но ASP.NET олицетворяет себя на уровне потока?

Попробуйте это:

type
  PTokenUser = ^TTokenUser;
  TTokenUser = packed record
    User: SID_AND_ATTRIBUTES;
  end;

function GetCurrentUserName(out DomainName, UserName: string): Boolean;
var
  Token: THandle;
  InfoSize, UserNameSize, DomainNameSize: Cardinal;
  User: PTokenUser;
  Use: SID_NAME_USE;
  _DomainName, _UserName: array[0..255] of Char;
begin
  Result := False;
  DomainName := '';
  UserName := '';

  Token := 0;
  if not OpenThreadToken(GetCurrentThread, TOKEN_QUERY, True, Token) then
  begin
    if GetLastError = ERROR_NO_TOKEN then // current thread is not impersonating, try process token
    begin
      if not OpenProcessToken(GetCurrentProcess, TOKEN_QUERY, Token) then
        Exit;
    end
    else
      Exit;
  end;
  try
    GetTokenInformation(Token, TokenUser, nil, 0, InfoSize);
    User := AllocMem(InfoSize * 2);
    try
      if GetTokenInformation(Token, TokenUser, User, InfoSize * 2, InfoSize) then
      begin
        DomainNameSize := SizeOf(_DomainName);
        UserNameSize := SizeOf(_UserName);

        Result := LookupAccountSid(nil, User^.User.Sid, _UserName, UserNameSize, _DomainName, DomainNameSize, Use);

        if Result then
        begin
          SetString(DomainName, _DomainName, StrLen(_DomainName));
          SetString(UserName, _UserName, StrLen(_UserName));
        end;
      end;
    finally
      FreeMem(User);
    end;
  finally
    CloseHandle(Token);
  end;
end;

Пример использования:

var
  DomainName, UserName: string;
begin
  if not GetCurrentUserName(DomainName, UserName) then
    RaiseLastOSError;
  Writeln(Format('%s\%s', [DomainName, UserName]));
end;

Надеюсь, это поможет.

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