You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TIdHttp重定向时自定义Authorization头认证异常求助

解决TIdHttp重定向时携带Authorization头导致Azure Blob 400错误的问题

从你提供的日志来看,问题的根源非常清晰:你的Authorization头被Indy自动带到了重定向后的Azure Blob存储请求中,但Blob服务并不接受Bearer Token认证。

问题分析

原API返回301重定向到Azure Blob的URL,这个URL已经包含了完整的SAS(Shared Access Signature)参数(就是URL里的sig=部分),这是Azure Blob合法的认证方式。但你的TIdHttp在重定向时,把原请求的Authorization: Bearer mysecrettoken头也一起发送给了Blob服务器,而Blob服务识别不了这种Bearer Token格式,于是返回InvalidAuthenticationInfo错误。

解决方案

你需要告诉TIdHttp:当重定向到不同主机时,不要携带Authorization头。这可以通过TIdHttp.OnRedirect事件来实现,在事件中检查目标URL的主机是否和原请求一致,不一致就移除Authorization头。

修改你的代码如下:

procedure APIRequest(const url, token: string; request, response: TStream);
var
  http: TIdHttp;
  ssl: TIdSSLIOHandlerSocketOpenSSL;
  OriginalHost: string;
begin
  http := TIdHttp.Create(nil);
  ssl := TIdSSLIOHandlerSocketOpenSSL.Create(http);
  try
    ssl.SSLOptions.SSLVersions := [sslvTLSv1_2];
    http.IOHandler := ssl;
    http.HandleRedirects := true;
    http.Request.CustomHeaders.Clear;
    http.Request.Accept := 'application/json';
    http.Request.CustomHeaders.FoldLines := false;
    http.Request.CustomHeaders.Values['Authorization'] := 'Bearer ' + token;

    // 获取原请求的主机名
    OriginalHost := TIdURI.Create(url).Host;
    // 绑定重定向事件
    http.OnRedirect := procedure(Sender: TObject; var dest: string; var NumRedirect: Integer; var Handled: Boolean; var VMethod: string)
    var
      RedirectURI: TIdURI;
    begin
      RedirectURI := TIdURI.Create(dest);
      try
        // 如果重定向目标主机和原主机不同,移除Authorization头
        if RedirectURI.Host <> OriginalHost then
        begin
          (Sender as TIdHttp).Request.CustomHeaders.Values['Authorization'] := '';
        end;
      finally
        RedirectURI.Free;
      end;
    end;

    try
      if request = nil then
        http.Get(url, response)
      else
        http.Post(url, request, response);
    except
      on e: EIdHTTPProtocolException do
      begin
        if response is TStringStream then
          (response as TStringStream).WriteString(e.ErrorMessage);
      end;
    end;
  finally
    http.Free;
  end;
end;

补充说明

  1. 安全角度:跨主机携带Authorization头本身就是不安全的行为,可能导致敏感的Token泄露给第三方服务器,所以这个处理方式也符合安全最佳实践。
  2. Indy默认行为:Indy的HandleRedirects默认会保留所有自定义头,包括Authorization,这在同主机重定向时是合理的,但跨主机时就会出问题。
  3. Azure Blob认证:Blob存储的认证要么用SAS参数,要么用Account Key生成的Authorization头(格式是Authorization: SharedKey <account>:<signature>),绝对不会接受Bearer Token,所以必须移除原头。

这样修改后,重定向到Blob存储时就不会携带Bearer Token,而是使用URL中的SAS参数进行认证,就能正常获取到文件了。

内容的提问来源于stack exchange,提问作者complete_stranger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:09:01