如何使用 Indy 响应摘要式访问身份验证



我正在尝试将响应发送回请求摘要访问身份验证的服务器

....
FResponseHeader.Text := FResponseText;// received header.
FResponseHeader.ProcessHeaders;
....
WriteLn(FResponseHeader.WWWAuthenticate); //WWW-Authenticate: Digest realm="xxxx.com", nonce="fq1uvocyzvr17e6a5syproazd5phwdvhvlc5", stale=false, algorithm=MD5, qop="auth"
LIdAuthentication := TIdDigestAuthentication.Create;
try
LIdAuthentication.Username := FUser;
LIdAuthentication.Password := FPass;
LIdAuthentication.Uri      := FURI;
LIdAuthentication.Method   := GetMsgTypeString(FResponseHeader.RequestMethods);
LIdAuthentication.Params.Values['Authorization'] := FResponseHeader.WWWAuthenticate;
LIdAuthentication.AuthParams.AddValue('Digest', FResponseHeader.WWWAuthenticate);
for I := 0 to LIdAuthentication.Steps do
LIdAuthentication.Next;
Result := LIdAuthentication.Authentication;
finally
LIdAuthentication.Free;
end;

我从服务器得到了401

创建授权标头的正确方法是什么?

TIdDigestAuthentication(和其他TIdAuthentication派生类(旨在与TIdHTTP一起使用,而不是独立使用。

如果使用TIdHTTP与服务器通信,则根本不需要手动管理 Digest 身份验证。如果服务器在其WWW-Authenticate标头中请求Digest,并且IdAuthenticationDigest(或IdAllAuthentications(在您的uses子句中,则TIdHTTP将自动为您发送摘要响应。您唯一需要关心的是:

  • 设置初始身份验证尝试的TIdHTTP.Request.UsernameTIdHTTP.Request.Password属性。

  • 设置TIdHTTP.OnAuthorization事件处理程序以处理服务器拒绝当前Username/Password的可能性,以便您可以提供新值进行重试,也可以在提示用户后提供。

  • (可选(设置TIdHTTP.OnSelectProxyAuthorization事件处理程序,以选择在服务器请求多个方案时要使用的身份验证方案,和/或如果要控制哪个方案优先于其他方案。

例如:

uses
..., IdHTTP, IdAuthenticationDigest;
...
IdHTTP1.OnAuthorization := AuthRequested;
IdHTTP1.Request.Username := ...; // initial username
IdHTTP1.Request.Password := ...; // initial password
IdHTTP1.Get(...);
...
procedure TMyClass.AuthRequested(Sender: TObject; Authentication: TIdAuthentication; var Handled: Boolean);
begin
if (new credentials are available) then
begin
Authentication.Username := ...; // new username
Authentication.Password := ...; // new password
Handled := True;
end else
Handled := False;
end;

话虽如此,如果你想使用TIdDigestAuthentication独立,那么你应该像TIdHTTP使用它一样使用它,例如:

LIdAuthentication := TIdDigestAuthentication.Create;
try
LIdAuthentication.SetRequest(FGetMsgTypeString(FResponseHeader.RequestMethods), FURI);
LIdAuthentication.Username := FUser;
LIdAuthentication.Password := FPass;
LIdAuthentication.Params.Values['Authorization'] := LIdAuthentication.Authentication;
LIdAuthentication.AuthParams := FResponseHeader.WWWAuthenticate; // assuming WWWAuthenticate is a TIdHeaderList...
repeat
case LIdAuthentication.Next of
wnAskTheProgram:
begin
// set LIdAuthentication.Username and LIdAuthentication.Password to new credentials to retry...
end;
wnDoRequest:
begin
// send new request with LIdAuthentication.Authentication in the 'Authorization' header...
Result := LIdAuthentication.Authentication;
Exit;
end;
wnFail:
begin
// error handling ...
Result := '';
Exit;
end;
end;
until False;
finally
LIdAuthentication.Free;
end;

最新更新