如何在Delphi XE7中为THTTPRIO的SOAP请求添加Authorization头?
在Delphi XE7中使用THTTPRIO调用SOAP接口时,无法添加Authorization: Basic YjNm...Uo0Z1Y0cA==请求头,但通过SoapUI测试请求完全正常,请求示例如下:
POST /ClientServices/ClientServPort.svc HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: text/xml;charset=UTF-8
SOAPAction: "getUserList"
Authorization: Basic YjNm...Uo0Z1Y0cA==
Content-Length: 436
Host: eclienttest.abc.com
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.5.5 (Java/16.0.2)<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:en="http:/abc.com/eUserList/">
soapenv:Header/
soapenv:Body
en:getUserListRequest
en:RoleAAA</en:Role>
</en:getUserListRequest>
</soapenv:Body>
</soapenv:Envelope>
以下是几种可行的解决方法:
方法1:直接通过HTTPWebNode添加请求头
THTTPRIO的HTTPWebNode属性可直接操作HTTP请求头,代码示例:
var HTTPRIO1: THTTPRIO; AuthToken: string; begin HTTPRIO1 := THTTPRIO.Create(nil); try // 填入预先编码好的Basic认证Token AuthToken := 'Basic YjNm...Uo0Z1Y0cA=='; // 为请求添加Authorization头 (HTTPRIO1.HTTPWebNode as THTTPWebNode).HTTP.AddCustomHeader('Authorization', AuthToken); // 设置SOAP服务地址并调用接口方法 HTTPRIO1.URL := 'http://eclienttest.abc.com/ClientServices/ClientServPort.svc'; // 例如:HTTPRIO1.getUserList('AAA'); finally HTTPRIO1.Free; end; end;
方法2:通过OnBeforeExecute事件动态添加
如果需要在每次接口调用前都注入请求头,可使用OnBeforeExecute事件,避免重复设置:
procedure TForm1.HTTPRIO1BeforeExecute(const MethodName: string; SOAPRequest: TStream); var WebNode: THTTPWebNode; AuthToken: string; begin WebNode := HTTPRIO1.HTTPWebNode as THTTPWebNode; AuthToken := 'Basic YjNm...Uo0Z1Y0cA=='; // 先移除已存在的Authorization头,防止重复添加 WebNode.HTTP.RemoveCustomHeader('Authorization'); WebNode.HTTP.AddCustomHeader('Authorization', AuthToken); end;
绑定事件的代码:
HTTPRIO1.OnBeforeExecute := HTTPRIO1BeforeExecute;
方法3:关联TSOAPHTTPTrans组件设置请求头
如果前两种方法不生效,可以单独创建TSOAPHTTPTrans组件,配置请求头后关联到THTTPRIO:
var HTTPRIO1: THTTPRIO; SOAPHTTPTrans1: TSOAPHTTPTrans; AuthToken: string; begin SOAPHTTPTrans1 := TSOAPHTTPTrans.Create(nil); HTTPRIO1 := THTTPRIO.Create(nil); try AuthToken := 'Basic YjNm...Uo0Z1Y0cA=='; SOAPHTTPTrans1.AddCustomHeader('Authorization', AuthToken); // 将SOAPHTTPTrans关联到HTTPRIO HTTPRIO1.HTTPWebNode := SOAPHTTPTrans1; HTTPRIO1.URL := 'http://eclienttest.abc.com/ClientServices/ClientServPort.svc'; // 调用接口方法 // ... finally HTTPRIO1.Free; SOAPHTTPTrans1.Free; end; end;
额外说明
- 如果你的认证Token不是预先编码好的,需要用
TIdEncoderMIME对用户名:密码字符串做Base64编码,示例:
AuthToken := 'Basic ' + TIdEncoderMIME.EncodeString('your_username:your_password');
- 确保THTTPRIO的
URL属性与SoapUI中的请求地址完全一致,避免因地址不匹配导致的请求失败。
内容的提问来源于stack exchange,提问作者user2417750

