Использование Fiddler в качестве прокси для отладки HTTP-запросов может быть полезным инструментом для разработчиков, но иногда может возникнуть необходимость передать сертификат в запросе. В данной статье мы рассмотрим, как это можно сделать в Object Pascal (Delphi) с помощью компонента Indy.
Во-первых, давайте рассмотрим код, который был предоставлен в контексте:
constructor TSpecialHTTP.Create(adbconn: IDBConnection; ...);
var
ssl: TIdSSLIOHandlerSocketOpenSSL;
dbresult: Variant;
q: IDataset;
begin
... other unimportant database stuff
// http is a private variable of the TSpecialHTTP class
http := TIdHTTP.Create;
// fiddler debug
http.ProxyParams.ProxyServer := '127.0.0.1';
http.ProxyParams.ProxyPort := 8888;
ssl := TIdSSLIOHandlerSocketOpenSSL.Create(http);
ssl.SSLOptions.SSLVersions := [sslvTLSv1_2];
http.IOHandler := ssl;
http.Request.ContentType := 'application/json; charset=utf-8';
http.Request.UserAgent := 'MyApplication';
http.Request.CustomHeaders.Clear;
http.Request.CustomHeaders.FoldLines := false; // without it doesn't work, dunno why
http.Request.CustomHeaders.Values[c_version] := GetMyVersion;
http.Request.CustomHeaders.Values['Authorization'] := 'Bearer ' + token;
CreateGUID(guid);
http.Request.CustomHeaders.Values[c_message_id] := Copy(GUIDToString(guid), 2, 36);
http.Request.CustomHeaders.Values[c_generating_utc] := DateToISO8601(TTimeZone.Local.ToUniversalTime(now), true);
http.Request.CustomHeaders.Values[c_version] := cdhrecords[cdht].version;
http.HTTPOptions := [hoForceEncodeParams, hoNoProtocolErrorException, hoWantProtocolErrorContent];
certstream := TBytesStream.Create;
if not VarIsNull(dbresult[1]) then begin
SaveVariantToStream(certstream, dbresult[1]);
certstream.Position := 0;
certstream.SaveToFile(certfile);
ssl.SSLOptions.CertFile := certfile;
ssl.SSLOptions.KeyFile := certfile;
ssl.SSLOptions.Mode := sslmBoth;
ssl.OnGetPassword := GetPassword;
end;
... again unimportant stuff
end;
В данном коде создается экземпляр компонента TIdHTTP и настраивается как прокси-сервер Fiddler. Затем создается экземпляр компонента TIdSSLIOHandlerSocketOpenSSL и настраивается для использования TLSv1.2. После этого устанавливаются заголовки запроса и настраиваются параметры SSL.
Если в базе данных есть сертификат, он сохраняется в файл и настраивается для использования в качестве клиентского сертификата. Однако, когда этот код отправляет запрос через Fiddler, сервер возвращает ошибку 401 с сообщением "Missing certificate or authorization header".
Причина этой ошибки заключается в том, что Fiddler не может использовать сертификат, который был установлен в коде. Fiddler ожидает, что сертификат будет установлен в личном хранилище сертификатов Windows, а не в файле.
Чтобы решить эту проблему, мы можем экспортировать сертификат из личного хранилища сертификатов Windows в файл формата CER и указать этот файл в скрипте Fiddler. Вот как это сделать:
Откройте магазин сертификатов, нажав на пуск и набрав "certmgr.msc".
Найдите сертификат, который вы хотите использовать, и щелкните его правой кнопкой мыши.
Выберите "Все задачи" > "Экспорт...".
Выберите "Экспорт в файл" и нажмите "Далее".
Выберите "Код сертификата" и нажмите "Далее".
Выберите "Кодирование в Base64" и нажмите "Далее".
Выберите место, где вы хотите сохранить файл, и нажмите "Экспорт".
Откройте скрипт Fiddler и добавьте следующую строку кода перед отправкой запроса:
Замените "C:\путь\к\сертификату.cer" на путь к файлу сертификата, который вы экспортировали на предыдущем шаге.
Теперь, когда вы отправляете запрос через Fiddler, сервер должен принять сертификат и ответить успешно.
Однако, есть альтернативное решение, которое не требует экспорта сертификата из личного хранилища сертификатов Windows. Можно использовать компонент Indy для установки сертификата напрямую в коде. Для этого нужно изменить код следующим образом:
constructor TSpecialHTTP.Create(adbconn: IDBConnection; ...);
var
ssl: TIdSSLIOHandlerSocketOpenSSL;
dbresult: Variant;
q: IDataset;
cert: TIdCert;
begin
... other unimportant database stuff
// http is a private variable of the TSpecialHTTP class
http := TIdHTTP.Create;
// fiddler debug
http.ProxyParams.ProxyServer := '127.0.0.1';
http.ProxyParams.ProxyPort := 8888;
ssl := TIdSSLIOHandlerSocketOpenSSL.Create(http);
ssl.SSLOptions.SSLVersions := [sslvTLSv1_2];
http.IOHandler := ssl;
http.Request.ContentType := 'application/json; charset=utf-8';
http.Request.UserAgent := 'MyApplication';
http.Request.CustomHeaders.Clear;
http.Request.CustomHeaders.FoldLines := false; // without it doesn't work, dunno why
http.Request.CustomHeaders.Values[c_version] := GetMyVersion;
http.Request.CustomHeaders.Values['Authorization'] := 'Bearer ' + token;
CreateGUID(guid);
http.Request.CustomHeaders.Values[c_message_id] := Copy(GUIDToString(guid), 2, 36);
http.Request.CustomHeaders.Values[c_generating_utc] := DateToISO8601(TTimeZone.Local.ToUniversalTime(now), true);
http.Request.CustomHeaders.Values[c_version] := cdhrecords[cdht].version;
http.HTTPOptions := [hoForceEncodeParams, hoNoProtocolErrorException, hoWantProtocolErrorContent];
if not VarIsNull(dbresult[1]) then begin
cert := TIdCert.Create;
cert.LoadFromStream(dbresult[1]);
ssl.SSLOptions.Cert := cert;
cert.Free;
end;
... again unimportant stuff
end;
В этом коде мы создаем экземпляр компонента TIdCert и загружаем в него сертификат из базы данных. Затем мы устанавливаем этот сертификат в качестве клиентского сертификата для компонента TIdSSLIOHandlerSocketOpenSSL.
Теперь, когда вы отправляете запрос через Fiddler, сервер должен принять сертификат и ответить успешно, без необходимости экспортировать сертификат из личного хранилища сертификатов Windows.
В заключение, мы рассмотрели два способа передачи сертификата в HTTP-запросе при использовании Fiddler в качестве прокси-сервера для отладки. Первый способ заключается в экспорте сертификата из личного хранилища сертификатов Windows в файл формата CER и указании этого файла в скрипте Fiddler. Второй способ заключается в использовании компонента Indy для установки сертификата напрямую в коде. Оба способа должны решить проблему с ошибкой 401 "Missing certificate or authorization header".
Статья описывает, как передать сертификат в HTTP-запросе при использовании Fiddler в качестве прокси-сервера для отладки в Object Pascal (Delphi) с помощью компонента Indy.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.