Гость
Форумы / Delphi [игнор отключен] [закрыт для гостей] / THTTPClient и базовая авторизация / 25 сообщений из 25, страница 1 из 1
18.08.2021, 19:27
    #40091591
vdix
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
THTTPClient и базовая авторизация
Приветствую, коллеги. Подскажите пожалуйста, как подружить THTTPClient с базовой авторизацией. Делал с инди - всё работает отлично, HTTPClient - либо ругается при попытке добавить авторизацию в виде хедера, либо возвращает 401 если делаю через ивент:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
type
  TAuthHandler = class
  public
    FUserName: String;
    FPassword: String;
    procedure NetHTTPClientAuthEvent(const Sender: TObject;
      AnAuthTarget: TAuthTargetType; const ARealm, AURL: string;
      var AUserName, APassword: string; var AbortAuth: Boolean;
      var Persistence: TAuthPersistenceType);
  end;

procedure TAuthHandler.NetHTTPClientAuthEvent(const Sender: TObject;
  AnAuthTarget: TAuthTargetType; const ARealm, AURL: string; var AUserName,
  APassword: string; var AbortAuth: Boolean;
  var Persistence: TAuthPersistenceType);
begin
  if AnAuthTarget = TAuthTargetType.Server then
  begin
    AUserName := FUserName;
    APassword := FPassword;
  end;
end;

function XSendRequest(Method, URL, CustomHeaders, Body, Login, Password: string): string;
var
  SourceStream: TStringStream;
  CustomHeadersList: TStrings;
  I: Integer;
  HTTPClient: THTTPClient;
  Request: IHTTPRequest;
  iResponse: IHTTPResponse;
  AuthHandler: TAuthHandler;

begin
  Result := '';
  SourceStream := TStringStream.Create(UTF8Encode(Body));
  HTTPClient := THTTPClient.Create;
  AuthHandler := TAuthHandler.Create;                           // basic auth
  try
    AuthHandler.FUserName := Login;                             // basic auth
    AuthHandler.FPassword := Password;                          // basic auth
    HTTPClient.AuthEvent := AuthHandler.NetHTTPClientAuthEvent; // basic auth
    try
      Request := HTTPClient.GetRequest(Method, URL);
(*
      // this raises (ENetHTTPRequestException) Error adding header: (87) The parameter is incorrect
      if Login + Password <> '' then
        Request.AddHeader('Authorization', 'Basic ' + TNetEncoding.Base64.Encode(Login + ':' + Password));
*)
      CustomHeadersList := TStringList.Create;
      try
        CustomHeadersList.Text := CustomHeaders;
        Request.SourceStream := SourceStream;
        for I := 0 to Pred(CustomHeadersList.Count) do
          Request.AddHeader(CustomHeadersList.Names[I],  CustomHeadersList.ValueFromIndex[I]);
      finally
        CustomHeadersList.Free;
      end;

      iResponse := HTTPClient.Execute(Request);
      Result := iResponse.ContentAsString;

    except
      on E: Exception do
      begin
        SendDebugError('SendRequest exception: '+E.Message);
      end
    end;
  finally
    AuthHandler.Free;
    SourceStream.Free;
    HTTPClient.Free;
  end;
end;
...
Рейтинг: 0 / 0
18.08.2021, 22:04
    #40091617
Cobalt747
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
THTTPClient и базовая авторизация
vdix,

Так указывай корректный параметр, всего-то делов...
...
Рейтинг: 0 / 0
19.08.2021, 02:00
    #40091641
vdix
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
THTTPClient и базовая авторизация
Можно конкретнее, будьте так любезны :) Я не могу найти, в каком месте ошибаюсь
...
Рейтинг: 0 / 0
19.08.2021, 10:19
    #40091698
Fr0sT-Brutal
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
THTTPClient и базовая авторизация
Код: pascal
1.
2.
3.
    if (User <> '') and (Pass <> '') then
      httpCli.CredentialsStorage.AddCredential(TCredentialsStorage.TCredential.Create(
        TAuthTargetType.Server, '', '', User, Pass));


вроде должно этого хватать. Но я не проверял, не на чем
...
Рейтинг: 0 / 0
19.08.2021, 11:18
    #40091723
vdix
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
THTTPClient и базовая авторизация
Fr0sT-Brutal, оно компилится, но не работает. Та же ошибка 401.
Самое главное, что код выполняется. И даже когда я ивент хендлер навешиваю - в этом хендлере код исполняется, я специально брейкпоинт ставил. Оно вроде как должно работать. Но не работает. То есть абсолютно то же самое делает, как будто кода с авторизацией нет. У меня 2 запроса последовательно выполняется: первый не требует авторизацию, второй - требует. Если к первому добавить авторизацию, он будет выполняться как и раньше, если ко второму не добавить - будет то же, как и в примерах выше: ошибка 401. При абсолютно те же вызовы, но через Indy, работают без проблем.
...
Рейтинг: 0 / 0
19.08.2021, 13:34
    #40091819
Fr0sT-Brutal
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
THTTPClient и базовая авторизация
Тогда бери сниффер и смотри, чего по факту отправляется. Можно даже свой сервер запустить, чтобы не связываться с перехватом https. Или example.com, он отвечает по http.
Заодно и сравни с тем, что пишет инди. Может, там дайджест авторизация, например
...
Рейтинг: 0 / 0
21.08.2021, 03:32
    #40092389
antox
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
THTTPClient и базовая авторизация
Я шлю через postman, для проверки правильности работы сервера, а что бы посмотреть что шлю - пишу php скрипт, тк нормальный сниффер найти не удалось. Где бы просто указать имя процесса и посмотреть реальный трафик. Обычно достаточно postmanи становится понятно, что надо сдать, что бы результат был нужным.
...
Рейтинг: 0 / 0
21.08.2021, 09:55
    #40092396
Vizit0r
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
THTTPClient и базовая авторизация
antox
Я шлю через postman, для проверки правильности работы сервера, а что бы посмотреть что шлю - пишу php скрипт, тк нормальный сниффер найти не удалось. Где бы просто указать имя процесса и посмотреть реальный трафик. Обычно достаточно postmanи становится понятно, что надо сдать, что бы результат был нужным.


хз как ты искал, их штук несколько рабочих сходу гуглится.

начни с Fiddler4.
...
Рейтинг: 0 / 0
22.08.2021, 22:21
    #40092548
vdix
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
THTTPClient и базовая авторизация
Я попробовал установить у себя Fiddler Classic. Он запускается, но в логе только 1 строчка. Прокси прописан на лупбек фиддлена, пробовал мониторить браузеры - даже их не ловит. Ни HTTP, ни HTTPS (сертификат ставил).
Установил Wireshark - этот ловит всё, но отфильтровать и понять, что же там отсылается мне не удалось, все пакеты зашифрованы.

Коллега потестил у себя через фиддлер (у него работает) - там видно, что удалённому серверу просто не отправляются логин и пароль в заголовке (т.е. в заголовке отсутствует Authorization).

Кстати, если посоветуете какой-то HTTPS сниффер/дебаггер или расскажете, как заставить работать фиддлер - буду весьма благодарен.
...
Рейтинг: 0 / 0
22.08.2021, 22:32
    #40092550
Cobalt747
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
THTTPClient и базовая авторизация
vdix,

Так пройдись отладкой по коду, он же есть в исходниках, ну ты чё?
...
Рейтинг: 0 / 0
23.08.2021, 05:38
    #40092567
asutp2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
THTTPClient и базовая авторизация
vdix,

попробуй заголовок передать в следующем виде:

Код: pascal
1.
2.
if (not User.IsEmpty) and (not Pass.IsEmpty) then
  Request.CustomHeaders['Authorization'] := 'Basic ' + TNetEncoding.Base64.Encode(Login + ':' + Password);
...
Рейтинг: 0 / 0
23.08.2021, 10:21
    #40092603
Fr0sT-Brutal
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
THTTPClient и базовая авторизация
vdix
Я попробовал установить у себя Fiddler Classic. Он запускается, но в логе только 1 строчка. Прокси прописан на лупбек фиддлена, пробовал мониторить браузеры - даже их не ловит. Ни HTTP, ни HTTPS (сертификат ставил).
Установил Wireshark - этот ловит всё, но отфильтровать и понять, что же там отсылается мне не удалось, все пакеты зашифрованы.

Коллега потестил у себя через фиддлер (у него работает) - там видно, что удалённому серверу просто не отправляются логин и пароль в заголовке (т.е. в заголовке отсутствует Authorization).

Кстати, если посоветуете какой-то HTTPS сниффер/дебаггер или расскажете, как заставить работать фиддлер - буду весьма благодарен.

Я ставил Wireshark portable, по мануалам прописал его серт, и все работает.
А что тебе мешает обратиться к серверу по HTTP и применить простейший SmSniff? Чтобы посмотреть запрос, совсем не обязательно, чтобы сервер слушал открытый протокол
...
Рейтинг: 0 / 0
23.08.2021, 11:27
    #40092627
vdix
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
THTTPClient и базовая авторизация
Cobalt747, по коду прошёлся. Если в хэдер попытаться добавить авторизацию, то вызовется raise ENetHTTPRequestException, если не добавить, то не смотря на нормально отрабатывающий HTTPClient.CredentialsStorage.AddCredential() или вызывающийся NetHTTPClientAuthEvent - сам THTTPClient добавляет только передаваемые в него хэдеры, а в них авторизации нет. В результате отправляет запрос без авторизации в хэдере, вот сервак его и посылает.

asutp2, в классе таких свойств нет. Пробовал через Request.AddHeader() и свойство Request.HeaderValue[] - в результате ошибка 87. Пробовал в HTTPClient.Execute() передавать заголовок с авторизацией - та же ошибка 87.
...
Рейтинг: 0 / 0
23.08.2021, 11:36
    #40092632
asutp2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
THTTPClient и базовая авторизация
vdix,

действительно, в моем примере вместо Request .CustomHeaders['Authorization'] нужно указать HTTPClient .CustomHeaders['Authorization']
...
Рейтинг: 0 / 0
23.08.2021, 12:16
    #40092644
vdix
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
THTTPClient и базовая авторизация
asutp2, из HTTPClient.CustomHeaders хэдеры не передаются в HTTPClient.Execute(). При том не только Authorization, но и вообще любые, только что проверил.
...
Рейтинг: 0 / 0
23.08.2021, 12:41
    #40092650
asutp2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
THTTPClient и базовая авторизация
vdix,

а у тебя какая версия делфи?
и почему кстати используешь именно Execute? Например при работе с Post, Get заголовки передаются без проблем
...
Рейтинг: 0 / 0
23.08.2021, 13:17
    #40092658
vdix
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
THTTPClient и базовая авторизация
У нас используется Delphi 10.2 upd.2. Ну да, не самый свежак, но и не дремучий лес. Постоянно обновляться и переустанавливать все компоненты - и недёшево, и довольно трудоёмко.

Execute() использую чтобы можно было передавать любой метод и не делать case IndexStr(). Только что попробовал использовать конкретно метод HTTPClient.Post() - результат тот же самый: либо нет заголовка, либо ошибка 87
...
Рейтинг: 0 / 0
23.08.2021, 13:37
    #40092665
asutp2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
THTTPClient и базовая авторизация
vdix,

насчет 10.2 не скажу, а вот в 10.3.3 и 10.4.2 TNetHTTPClient с заголовками работает нормально
...
Рейтинг: 0 / 0
23.08.2021, 13:54
    #40092671
s62
s62
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
THTTPClient и базовая авторизация
vdix,
ради интереса попробовал, сделал на локальном Apache папку с basic authentication, код, как у вас в обработчике события OnAuthEvent, всё нормально сработало. И по http, и по https, правда с тестовым сертификатом, так что в OnValidateServerCertificate просто написал Accepted := True; , а то компонент не принимает сертификат. Использовал метод Get.
Код: pascal
1.
2.
3.
4.
procedure TForm1.BtnClick(Sender: TObject);
begin
  Memo.Lines.Text := NetHTTPClient.Get('https://localhost/secret/').ContentAsString(TEncoding.UTF8);
end;


Delphi 10.4 CE.
...
Рейтинг: 0 / 0
24.08.2021, 11:08
    #40092868
vdix
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
THTTPClient и базовая авторизация
Видимо действительно что-то с компонентом. Synapse и Indy авторизуются, но оба используют OpenSSL. HTTPClient и NetHTTPClient (фактически обёртка над первым) - не хотят работать с авторизацией.
...
Рейтинг: 0 / 0
24.08.2021, 17:56
    #40092949
Fr0sT-Brutal
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
THTTPClient и базовая авторизация
Траффик поснифал или так и будешь методом тыка вслепую выснять?
...
Рейтинг: 0 / 0
25.08.2021, 13:38
    #40093089
vdix
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
THTTPClient и базовая авторизация
Со сниффером не срослось, написал свой сервер и вывел в лог запрос, все заголовки и пэйлоад.
...
Рейтинг: 0 / 0
26.08.2021, 11:40
    #40093246
Fr0sT-Brutal
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
THTTPClient и базовая авторизация
Ну тоже вариант. И как? Есть разница в запросах?
...
Рейтинг: 0 / 0
27.08.2021, 14:05
    #40093458
vdix
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
THTTPClient и базовая авторизация
Конечно есть. Indy и Synapse дают в заголовке нормальную строку базовой авторизации, а оба HTTPClient-а - нет, какие бы ухищрения я не использовал: и через ивент, и устанавливая заголовки как клиенту, так и запросу, и используя AddCredential - либо это не делает ничего, либо в рантайме выдаёт ошибку 87.
...
Рейтинг: 0 / 0
27.08.2021, 18:20
    #40093538
Fr0sT-Brutal
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
THTTPClient и базовая авторизация
Иди пошаговой отладкой и смотри, почему не добавляется хэдер
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / THTTPClient и базовая авторизация / 25 сообщений из 25, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]