代码之家  ›  专栏  ›  技术社区  ›  Steve

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

  •  1
  • Steve  · 技术社区  · 16 年前

    我需要获取当前登录用户名?当我从ASP.NET调用在Windows身份验证模式下工作的代码时,我需要它正常工作。也就是说,在这种情况下,我不想获取aspnet用户,而是希望获得模拟用户。这和我以前的事有关 question . 我尝试的一切都会回来 ASPNET .

    3 回复  |  直到 9 年前
        1
  •  3
  •   Matt user129975    9 年前

    在您的另一个问题中,您写到您已将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();
    }
    

    更新:

    如果从Web窗体页的代码隐藏中调用了ComAbject,则可以尝试将Web窗体页的AspCompat属性设置为true。

    见:

    “身份”标签确保 执行请求的线程(MTA 线程)将模拟其安全性 中指定的用户上下文 标记但我们的sta-com对象 最终在默认情况下创建 未模拟的STA线程, 使其获取安全上下文 过程(即 最不强大的用户)。

        2
  •  1
  •   Ondrej Kelle    16 年前

    也许你 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;
    

    希望这有帮助。

        3
  •  1
  •   Remko    16 年前

    这是我的密码的一部分 LoadProfile 工具,它在Delphi2010中很好地工作:

    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);