如何使用 Indy 响应摘要式访问认证
How to response to digest access authentication with 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。
创建授权的正确方法是什么Header?
TIdDigestAuthentication
(以及其他 TIdAuthentication
派生的 类)旨在与 TIdHTTP
一起使用,而不是独立使用。
如果您使用 TIdHTTP
与服务器通信,则根本不需要手动管理摘要式身份验证。如果服务器在其 WWW-Authenticate
header 中请求 Digest
,并且如果 IdAuthenticationDigest
(或 IdAllAuthentications
)在您的 uses
子句中,则 TIdHTTP
将自动为您发送摘要响应。您唯一需要关心的事情是:
为初始身份验证尝试设置 TIdHTTP.Request.Username
和 TIdHTTP.Request.Password
属性。
设置一个 TIdHTTP.OnAuthorization
事件处理程序来处理服务器拒绝当前 Username
/Password
的可能性,以便您可以提供新的重试值,可选在提示用户之后。
可选地设置一个TIdHTTP.OnSelectProxyAuthorization
事件处理程序来选择在服务器请求多个方案时使用哪个认证方案,and/or如果你想控制哪个方案优先超过其他人。
例如:
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;
我正在尝试将响应发送回请求摘要式访问身份验证
的服务器 ....
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。
创建授权的正确方法是什么Header?
TIdDigestAuthentication
(以及其他 TIdAuthentication
派生的 类)旨在与 TIdHTTP
一起使用,而不是独立使用。
如果您使用 TIdHTTP
与服务器通信,则根本不需要手动管理摘要式身份验证。如果服务器在其 WWW-Authenticate
header 中请求 Digest
,并且如果 IdAuthenticationDigest
(或 IdAllAuthentications
)在您的 uses
子句中,则 TIdHTTP
将自动为您发送摘要响应。您唯一需要关心的事情是:
为初始身份验证尝试设置
TIdHTTP.Request.Username
和TIdHTTP.Request.Password
属性。设置一个
TIdHTTP.OnAuthorization
事件处理程序来处理服务器拒绝当前Username
/Password
的可能性,以便您可以提供新的重试值,可选在提示用户之后。可选地设置一个
TIdHTTP.OnSelectProxyAuthorization
事件处理程序来选择在服务器请求多个方案时使用哪个认证方案,and/or如果你想控制哪个方案优先超过其他人。
例如:
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;