如何获取当前登录的用户,包括Delphi 2009中的域?

时间:2009-11-26 14:08:30

标签: asp.net delphi com windows-authentication

我需要获取当前登录的用户名吗?当我从ASP.NET身份验证模式中调用代码时,我需要这个才能正常工作。即我不想在那种情况下获得ASPNET用户,而是模仿用户。这与我之前的question有关。我尝试的所有内容都会返回 ASPNET

3 个答案:

答案 0 :(得分:3)

在您提出的另一个问题中,您已将ASP.NET配置为使用带有模拟的Windows身份验证:

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

ASP.NET应用程序是否显示正确的凭据(用户和域)?

您是否正在使用正确的Identity上下文调用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();
}

更新

如果从Web表单页面的代码中调用COM abject,您可以尝试将Web表单页面的ASPCOMPAT属性设置为true。

见:

  

“身份”标签确保了   线程执行请求(MTA   线程)将冒充其安全性   上下文中指定的用户    标签,但我们的STA COM对象   最终是在默认情况下创建的   没有冒充的STA线程,   导致它获得安全上下文   过程(这是IUSR_XXX -   所有人中最不强大的用户。)

答案 1 :(得分:1)

也许您的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;

希望这有帮助。

答案 2 :(得分:1)

这是我的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);