Jak wysłać HTTP GET z Authorization Digest?

0

Witajcie,

Temat wydaje się mega prosty artykułów jest od groma na neci ale mimo wszystko utknąłem. Mamy najprostszy na świecie kod:

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdHTTP,
  StdCtrls, IdAuthenticationDigest;

type
  TForm1 = class(TForm)
    Button1: TButton;
    IdHTTP1: TIdHTTP;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
    IdHTTP1.Request.Username := 'admin';
    IdHTTP1.Request.Password := 'xxx';
    IdHTTP1.Get('http://ADRES_IP/cgi-bin/ptz.cgi?action=moveAbsolutely&channel=1&arg1=0.2&arg2=0&arg3=0');
end;

zgodnie z wytycznymi znalezionymi na necie dodałem IdAuthenticationDigest ale mimo wszystko dostaję
HTTP/1.1 401 Unauthorized.

co ciekawe to przy użyciu postmana:
screenshot-20211105092926.png
działa poprawnie.

Możecie coś podpowiedzieć? Delphi 2010 niestety :(

0

Nie wiem ale się wypowiem.

Jaką masz wersję Indy bo martwi mnie te twoje Delphi 2010? Czy IdAuthenticationDigest użyłeś ze swojego pakietu czy może dołożyłeś jakieś pobrane z Internetu? Nie jest to jakiś staroć aby?

0

Też się nie znam na Indy ale pierwszy link z netu
https://stackoverflow.com/questions/14645346/indy-delphi-http-client-and-digest-authentication
Jaki już ustawiłeś to ok, ale nie podałeś co ewentualnie zmieniłeś w dfm.

0

@robertz68: teorytycznie Indy 10, a IdAuthenticationDigest użyłem standardowy. Ogólnie on próbuje jakiś MD5 wygenerować ale jest on zdecydowanie niepoprawny. @Clarc ja patrzyłem na to i w dfm próbowałem najróżniejsze opcje przestawiać, basic authentication true/false, HTTPOptions.hoInProcessAuth true/false zdarzenia OnAuthorization i OnSelectAuthorization i nic ... za każdym razem to samo. Mam wrażenie, że indy używa czegoś innego do generowania MD5 i te hashe są inne niż w przypadku CURL ale to tylko moje domysły.

Ogólnie problem "obszedłem" wywołując shellexecute i uruchamiając CURL więc mi działa ale wolałbym jednak zrobić to wewnątrz aplikacji bez zewnętrznych narzędzi ;)

1

Zobacz Fiddlerem co tam leci do i wtedy zobaczysz jakie są różnice.

1

A jak na testowym serwerze? Wszyskie komponenty na domyślnych to co Object Onspector ustawione w kodzie. Ponieważ to HTTPS oczywiście wymaga obecnosci bibliotek Open SSL.

procedure TForm1.Button1Click(Sender: TObject);
const
  URL = 'https://jigsaw.w3.org/HTTP/Digest/'; //testowy serwer dlatego dane jawne
  USER = 'guest';
  PASS = 'guest';
begin
  IdHTTP1.Request.Username := USER;
  IdHTTP1.Request.Password := PASS;
  Memo1.Text:= IdHTTP1.Get(URL);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  IdSSLIOHandlerSocketOpenSSL1.SSLOptions.Method:= sslvTLSv1_2;  //opcje które można ustawić w object inspector
  IdHTTP1.HTTPOptions:= [hoInProcessAuth];
  IdHTTP1.IOHandler:= IdSSLIOHandlerSocketOpenSSL1;
  IdHTTP1.HandleRedirects:= True; //BARDZO WAŻNE!
end;
0

@kAzek: też od razu pomyślałem o ssl-u ale z tego co widziałem na screenie to kolega łączy się jednak ze stroną http, dlatego odpuściłem sobie tą ścieżkę dedukcji.

0

@robertz68 Ja bardziej bym się skłaniał w stronę nie ustawienia HandleRedirects (z pozoru niby nic najwyżej błąd 301 , 302 itp a tu ważne). Szczerze mówiąc nie wiem i nie mam czasu wnikać jak i dlaczego tak się to dobywa ale serwer wysyła nawet kilkukrotnie zapytanie z nagłówkiem w postaci:
Authorization: Digest username="guest", realm="test", nonce="72cd227c10fbe14a1c62b5b558bfcd6a", uri="/HTTP/Digest/", response="da002e5455bd740a7bdb4d4f9c526fc9"
i jakoś po kolejnej próbie trafia na poprawne (nie wiem różne algorytmy obliczania tego nonce i response) czy coś w każdym razie to się zmienia i w końcu trafia na poprawy a bez HandleRedirects nie ma na to szans tylko wywala 401 a z obsługą przekierowań za 1 ale i może nawet 2 lub 3 a nawet 4 trafia na właściwy. Dlaczego tak? Nie wiem przeglądarka też tak robi... jak kogoś to interesuje trzeba by się wgłębić w specyfikację tego typu autoryzacji.

0

@kAzek: Próbowałem z tym IdSSLIOHandlerSocketOpenSSL1 ale albo krzyczy 401 albo

Error creating SSL context.

także to dalej nie to ... nie wiem czy to przypadkiem nie jest wina tego, że to jest dość stare delphi (i indy), a kamerka jest z tego roku ...

0

@woolfik ale próbowałeś ten testowy kod z testowym serwerem który dałem?
Jeżeli nawet on nie działa to później zobaczę na jeszcze starszym D7 czy zadziała.

0

@kAzek: tak
First chance exception at $76FFC5AF. Exception class EIdOSSLCreatingContextError with message 'Error creating SSL context.'. Process Project2.exe (8548)

1

@woolfik na Delphi 7 działa z tym że ja tam mam zainstalowane Indy w wersji 10.6.2.0
Na pewno masz biblioteki SSL w folderze z plikiem wykonywalnym? U mnie to wygląda tak:
screen1.png
Pierwsza próba pierwsze (pierwsze 4 pozycje na liście, bo widać Indy wysłało 4 żądania) to bez bibliotek DLL jak zawsze 401 a druga próba dostaje też 401 ale zaraz 200 czyli wszystko OK.
Jak coś bibliotek znajdziesz na https://github.com/IndySockets/OpenSSL-Binaries wersja bibliotek zależy od wersji Indy ja u siebie użyłem dość nieaktualnych 1.0.2f.

0

@kAzek: Coś jest nie tak z INDY bo jak ten sam kod uruchomiłem na XE5 to poszło od ręki. W d2010 mam indy140.bpl w XE5 mam indy190.bpl. Natomiast co do dll to w obu przypadkach korzystałem z tych samych i na XE5 działa bezproblemowo.

0

No właśnie może któraś wersja miała jakiś błąd i nie ważna wersja Delphi ani nawet bibliotek SSL tylko ważna jest wersja Indy. Albo w ogole w starych Indy nie działa to w D7 Indy 10.6.2.0 też było aktualizowane z tym że jakiś czas temu ale na pewno dużo później niż było Delphi 2010.

1 użytkowników online, w tym zalogowanych: 0, gości: 1