【问题标题】:401 With Indy IdHttp Digest Authentication in Delphi XE在 Delphi XE 中使用 Indy IdHttp Digest 身份验证的 401
【发布时间】:2012-08-21 14:21:09
【问题描述】:

尝试使用 Digest 对合作伙伴的使用 Delphi XE 的 Web 服务执行 get()。

我已将IdAuthenticationDigest 包含在uses 子句中,该子句应该会自动根据我所阅读的内容起作用-但我一定遗漏了一些东西,因为我得到了401 Unauthorized。

代码:

begin
  // Init request:   
  IdHttp := TIdHttp.Create(nil);
  try
    idHttp.Request.ContentType := self.inputType; // 'application/xml'
    idHttp.Request.Accept := self.outputType; //'application/json';

    // Set request method:
    idHttp.Request.Method := Method; // 'Get'
    // Set username and password:
    idHttp.Request.BasicAuthentication := False;
    // IdHttp.Request.Username/Password also fails
    IdHttp.Request.Authentication.Username := 'xx';
    IdHttp.Request.Authentication.password := 'xx';

    IdHttp.Request.ContentLength := Length(Body);

    // Send request:
    if Method = 'GET' then
      Result := idHttp.Get(self.ServiceHost + URI)
    else
    if Method = 'POST' then
      Result := idHttp.Post(self.ServiceHost + URI, SendStream);

   finally
    idHttp.Free;
   end;
end;

【问题讨论】:

    标签: delphi indy digest-authentication


    【解决方案1】:

    您需要设置Request.UsernameRequest.Password 属性,而不是使用Request.Authentication 属性。此外,根本不要设置Request.MethodRequest.ContentLength 属性。所有这三个属性都由TIdHTTP 内部管理。

      // Init request:   
      IdHttp := TIdHttp.Create(nil);
      try
        idHttp.Request.ContentType := self.inputType; // 'application/xml'
        idHttp.Request.Accept := self.outputType; //'application/json';
    
        // Set username and password:
        idHttp.Request.BasicAuthentication := False;
        IdHttp.Request.Username := 'xx';
        IdHttp.Request.Password := 'xx';
    
        // Send request:
        if Method = 'GET' then
          Result := IdHttp.Get(self.ServiceHost + URI)
        else
        if Method = 'POST' then
          Result := IdHttp.Post(self.ServiceHost + URI, SendStream);
       finally
        IdHttp.Free;
       end;
    

    【讨论】:

    • 谢谢,试过了(Request.Username 是我开始的方式),仍然失败,出现 401 - 资源需要身份验证。
    • 那么请提供来回的实际 HTTP 流量的跟踪日志。 TIdHTTP 正在发送错误的摘要请求,或者根本没有发送摘要请求。使用数据包嗅探器(如 Wireshark)或 Indy 自己的 TIdLog... 组件之一来捕获该流量。
    • 根本不发送摘要请求。
    • TIdHTTP.OnSelectAuthorization 事件中,AuthenticationClass 参数是否在输入时设置为TIdDigestAuthentication?如果不是,那么要么服务器一开始就没有请求摘要(您可以在同一事件中使用 AuthInfo 参数进行验证),或者 TIdDigestAuthentication 实际上并未向 TIdHTTP 注册。
    • 我刚刚确认AuthenticationClassOnSelectAuthorization 事件中被设置为TIdDigestAuthentication。我尝试联系的 API 合作伙伴声称缺少构成摘要请求的两个请求中的第二个。
    【解决方案2】:

    添加类似这样的 OnAuthorization 事件:

    procedure TForm1.IdHTTP1Authorization(Sender: TObject;
      Authentication: TIdAuthentication; var Handled: Boolean);
    begin
    Authentication.Username:='user';
    Authentication.Password:='passs'; 
    if Authentication is TIdDigestAuthentication then
      begin
        showmessage('onAuthorization: '+Authentication.Authentication);
        TIdDigestAuthentication(IdHTTP1.Request.Authentication).Uri:=IdHTTP1.Request.URL;
        TIdDigestAuthentication(Authentication).Method := 'GET';
      end;
    Handled:=true;
    end;
    

    有时 indy 会遗漏一些必要的信息。就我而言,我正在连接到 Tomcat 服务器,但这需要在发送摘要参数身份验证信息时使用 Get 方法。

    【讨论】:

    • 这个事件没有被触发。
    • 确保 IdHttp 的 basicAuthentication 设置为 false 并且 IdHttp.Request.Authentication.Username 和 IdHttp.Request.Authentication.password 为空。
    【解决方案3】:

    在执行 GET 之前,您还需要设置 hoInProcessAuth 标志。

    idHttp.HTTPOptions := idHttp.HTTPOptions + [hoInProcessAuth];
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-11
      • 2011-06-03
      • 2015-03-01
      • 2023-03-16
      • 1970-01-01
      相关资源
      最近更新 更多