我有一个在IIS下运行为ISAPI扩展的SOAP服务器。为了验证我决定使用IIS的内置基本身份验证。在SOAP服务器中,我只需要知道连接到ISAPI的用户的用户名。关于MSDN article:
在IIS处理请求之前,执行客户端身份验证以设置执行请求的进程的安全上下文(或标识)。
我希望使用函数GetUserName
获取调用者的用户名。
这是SOAP服务器的实现代码:
TTestSOAP = class(TSOAPDataModule, ITestSOAP)
public
function WhoAmI: String; stdcall;
end;
function TTestSOAP.WhoAmI: String;
var
WinName: String;
BufSize: DWord;
Buffer: PWideChar;
begin
BufSize:= 1024;
Buffer:= AllocMem(BufSize);
try
if GetUserName(Buffer, BufSize) then
SetString(WinName, Buffer, BufSize)
else
RaiseLastOSError;
finally
FreeMem(Buffer);
end;
Result:= Format('You are: %s', [WinName]);
end;
ISAPI dll是使用Delphi 2009构建的,并使用ISAPIThreadPool单元。
通常一切正常,我得到正确的用户名。但是在负载很重的情况下,我得到了错误的结果。即:在客户端,我创建连接到SOAP服务器的测试线程,在循环中调用WhoAmI函数5次并断开连接。使用不同的用户运行其中三个或更多个线程,WhoAmI函数返回的用户名将随机交换。 例如:作为'user1'连接的线程在5个调用中的某些(不是全部)上获得'you are:user2'。
有没有人知道这里发生了什么? 您是否知道在SOAPDataModule中获取用户名已通过IIS验证的安全且正确的用户名?
修改
做了一些测试和调试:
在WhoAmI函数实现中,我添加了此代码LogonName:= GetSOAPWebModule.Request.GetFieldByName('AUTH_USER');
。它报告的用户名与GetUserName相同。
似乎问题发生在客户端。关于客户的一些细节:
提到的线程创建HTTPRio组件(每个线程都有自己的HTTPRio)。对于授权,我设置了Rio.HTTPWebNode.UserName和Rio.HTTPWebNode.Password。在HTTPRio.HTTPWebNode.Connect(True)之后,我在循环中调用ITestSOAP(HTTPRio).WhoAmI。
HTTPRio背后的Winet是否可能与多个HTTPRio组件的用户名不匹配,每个组件在不同的线程中运行但是是同一个进程(应用程序)?