2015-03-23 5 views
1

Я пытаюсь проверить мой веб-сервиса с TIdHTTP (Indy 10.6.0 и Delphi xe5) этим кодом:Ошибка авторизации TIdHTTP над HTTPS, когда пароль русский

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; 

"Auser" и "APass" в UTF -8. Когда «APass» имеют одинаковые русские символы, я не могу войти в систему. Под "HTTP Анализ" Я вижу:

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

Decode из базы 64 (base64decode.org) мы можем видеть:

p8user:??????123 

Почему DefStringEncoding не работает?

ответ

3

TIdHTTP Система аутентификации не имеет понятия TIdIOHandler или ее DefStringEncoding.

Внутренний, TIdBasicAuthentication использует TIdEncoderMIME.Encode(), но без указания какой-либо кодировки. TIdEncoder.Encode() по умолчанию имеет 8-битное кодирование, и поэтому на него не влияет GIdDefaultTextEncoding.

Если вам нужно отправить UTF-8, закодированный пароль с BASIC аутентификации, вы должны кодировать UTF-8 данные о вручную и сохранить полученный октет в string, то кодер 8bit может обрабатывать октет как есть , например:

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

с другой стороны, DIGEST аутентификации Инди, например, использует TIdHashMessageDigest5.HashStringAsHex() и TIdHash.HashString() не по умолчанию для конкретной кодировки, это зависит от GIdDefaultTextEncoding.

Итак, вы должны быть осторожны с тем, как вы кодируете пароли, основываясь на том, какие аутентификации вы используете. Для учета descrepency, что вы могли бы попробовать не кодировать TIdHTTP.Request.Password себя, но вместо того, чтобы закодировать пароль в TIdHTTP.OnAuthorization случае вместо того, чтобы при BASIC аутентификации который используется:

Http.Request.Password := APass; 
... 
procedure TMyForm.HttpAuthorization(Sender: TObject; Authentication: TIdAuthentication; var Handled: Boolean); 
var 
    B: TIdBytes; 
begin 
    if Authentication is TIdBasicAuthentication then 
    begin 
    Authentication.Password := BytesToStringRaw(IndyTextEncoding_UTF8.GetBytes(TheDeisredPasswordHere)); 
    Handled := True; 
    end; 
end; 
+0

Он работает. Реми, большое спасибо за помощь и эффективность. –