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

Delphi RESTClient调用Azure公共RESTServer的OAuth2参数及超时问题排查

问题排查与解决方案

1. 优先解决网络超时问题(错误码12002)

  • 你提到ping Azure VM公网IP超时但能正常获取OAuth2令牌,说明Azure VM的入站安全规则未开放REST服务使用的8080端口(令牌请求走Azure AD的443端口,所以不受影响)。
  • 操作步骤:
    • 登录Azure门户,找到目标VM的网络安全组(NSG)
    • 添加入站规则:允许TCP协议、端口8080(或你计划使用的HTTPS端口443)、来源设为"任意"或指定客户端IP范围
  • 注意:如果改用HTTPS,需确保VM上配置了有效的SSL证书,或通过Azure Application Gateway做SSL终止

2. 修正REST请求参数的错误配置

(1)GET请求不能使用pkREQUESTBODY参数

GET协议规范中没有请求体,本地测试正常是因为DataSnap对参数处理较宽松,但公网环境下会导致请求异常。

  • 若接口设计为GET,将参数类型改为pkURLQUERY:
    RESTRequest1.Params.AddItem('MyKey1', 'MyValue1', TRESTRequestParameterKind.pkURLQUERY);
    RESTRequest1.Params.AddItem('MyKey2', 'MyValue2', TRESTRequestParameterKind.pkURLQUERY);
    
  • 若接口原本是POST(本地调用时用POST),则将RESTRequest1.Method改为rmPOST,保留pkREQUESTBODY参数

(2)正确设置Authorization请求头

直接用Params.AddItem添加Authorization会被当作URL参数或请求体参数,而非HTTP头,需明确指定为Header类型:

RESTRequest1.Params.AddHeader('Authorization', 'Bearer ' + FConnection.AuthToken);

3. Azure OAuth2 Scope配置与Delphi组件设置

  • Azure端配置:
    1. 在Azure AD的应用注册中,找到你的REST Server对应的API应用,添加自定义Scope(比如access_as_user)
    2. 在Client应用的API权限中,添加上述Scope并授予管理员同意
  • Delphi端设置:
    在TOAuth2Authenticator组件中指定Scope属性,确保请求令牌时包含该权限:
    OAuth2Authenticator5.Scope := 'api://<你的API应用ID>/access_as_user';
    
  • 验证令牌:用JWT解析工具(比如jwt.ms)获取到的access_token,检查scp字段是否包含配置的Scope,aud字段是否匹配你的API应用ID,不匹配的话API会拒绝访问

4. 修正后的调用代码示例

procedure MyForm.Button1Click(Sender: TObject);
var
  RESTClient1: TRESTClient;
  RESTRequest1: TRESTRequest;
  strImageJSON : string;
begin
  // 建议用HTTPS,需确保VM配置了SSL证书或通过网关转发
  RESTClient1 := TRESTClient.Create('https://<Azure Public IP>:443/'); 
  try
    RESTRequest1 := TRESTRequest.Create(nil);
    try
      // 根据接口实际设计选择Method,这里假设是POST
      RESTRequest1.Method := TRESTRequestMethod.rmPOST; 
      RESTRequest1.Resource := 'api/<MyAzureResource>'; // 不需要在Resource里加ClientID,除非你的API路由设计如此
      // POST请求用RequestBody参数
      RESTRequest1.Params.AddItem('MyKey1', 'MyValue1', TRESTRequestParameterKind.pkREQUESTBODY);
      RESTRequest1.Params.AddItem('MyKey2', 'MyValue2', TRESTRequestParameterKind.pkREQUESTBODY);
      // 正确添加Authorization头
      RESTRequest1.Params.AddHeader('Authorization','Bearer ' + FConnection.AuthToken);
      RESTRequest1.Client := RESTClient1;
      // 可以设置超时时间,避免默认过短
      RESTRequest1.Timeout := 30000; 
      RESTRequest1.Execute;
      strImageJSON := RESTRequest1.Response.Content;
    finally
      RESTRequest1.Free;
    end;
  finally
    RESTClient1.Free;
  end;
end;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 02:21:06