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