IIS の下で ISAPI 拡張として実行されている SOAP サーバーがあります。認証には、IIS の組み込みの基本認証を使用することにしました。SOAP サーバーでは、ISAPI に接続しているユーザーのユーザー名を知る必要があるだけです。MSDNの記事に関して:
IIS が要求を処理する前に、要求を実行するプロセスのセキュリティ コンテキスト (または ID) を設定するために、クライアントの認証が実行されます。
関数を使用して呼び出し元のユーザー名を取得したいと考えていました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 回呼び出して切断するテスト スレッドを作成します。これらのスレッドをそれぞれ異なるユーザーで 3 つ以上実行すると、WhoAmI 関数によって返されるユーザー名がランダムに交換されます。例: 'user1' として接続しているスレッドは、5 回の呼び出しの一部 (全部ではない) で 'You are: user2' を取得します。
ここで何が起こっているのか、手がかりを持っている人はいますか? クライアントが IIS に対して認証された SOAPDataModule でユーザー名を取得する安全で正しい方法を知っていますか?
編集:
さらにテストとデバッグを行いました: 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 コンポーネントのユーザー名を一致させない可能性はありますか?