密码为俄语时,授权失败TIdHTTP over HTTPS

时间:2015-03-23 07:31:45

标签: delphi encoding https indy delphi-xe5

我尝试使用此代码使用TIdHTTP(Indy 10.6.0和Delphi XE5)测试我的Web服务:

GIdDefaultTextEncoding := encUTF8;
HTTP.IOHandler.DefStringEncoding := IndyTextEncoding_UTF8;
Http.Request.UserName := AUser;
Http.Request.Password := APass;
Http.Request.Accept := 'text/javascript';
Http.Request.ContentType := 'application/json';
Http.Request.ContentEncoding := 'utf-8';
Http.Request.URL := 'https://sameService';
Http.MaxAuthRetries := 1;
Http.Request.BasicAuthentication := True;
TIdSSLIOHandlerSocketOpenSSL(HTTP.IOHandler).SSLOptions.Method := sslvSSLv3;
HTTP.HandleRedirects := True;

UTF-8中的“AUser”和“APass”。当“APass”有相同的俄罗斯字符时,我无法登录。 通过“HTTP Analyze”我看到:

...
Authorization: Basic cDh1c2VyOj8/Pz8/PzEyMw==

从Base 64解码(base64decode.org),我们可以看到:

p8user:??????123

为什么DefStringEncoding不起作用?

1 个答案:

答案 0 :(得分:3)

TIdHTTP的身份验证系统没有TIdIOHandlerDefStringEncoding属性的概念。

在内部,TIdBasicAuthentication使用TIdEncoderMIME.Encode(),但未指定任何编码。 TIdEncoder.Encode()默认为8位编码,因此不受GIdDefaultTextEncoding的影响。

如果您需要使用BASIC身份验证发送UTF-8编码密码,则必须手动编码UTF-8数据并将生成的八位字节存储到string,然后将8位编码器存储可以按原样处理八位字节,例如:

Http.Request.Password := BytesToStringRaw(IndyTextEncoding_UTF8.GetBytes(APass));

另一方面,Indy的DIGEST身份验证使用TIdHashMessageDigest5.HashStringAsHex(),而TIdHash.HashString()不会默认使用任何特定的编码,它取决于{{1 }}

因此,根据您使用的身份验证,您必须要小心如何编码密码。为了解释这种不确定性,您可以尝试的不是编码GIdDefaultTextEncoding本身,而是在TIdHTTP.Request.Password事件中编码密码,而不是在使用TIdHTTP.OnAuthorization身份验证时:

BASIC