AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Anmelden an Webmodul über IdHTTP
Thema durchsuchen
Ansicht
Themen-Optionen

Anmelden an Webmodul über IdHTTP

Ein Thema von fwn · begonnen am 8. Apr 2013 · letzter Beitrag vom 11. Apr 2013
Antwort Antwort
Seite 2 von 3     12 3      
Thom

Registriert seit: 19. Mai 2006
570 Beiträge
 
Delphi XE3 Professional
 
#11

AW: Anmelden an Webmodul über IdHTTP

  Alt 9. Apr 2013, 19:41
Hallo nahpets,

ich hatte gerade noch etwas den Quelltext überarbeitet:

Server:
Delphi-Quellcode:
procedure TWebModule1.WebModule1TestAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
var
  N: Integer;
  S: String;
begin
  S := String(Request.Authorization);
  N := Pos(' ',S);
  if N > 0 then
  begin
    Delete(S,1,N);
    S := TIdDecoderMIME.DecodeString(s);
    N := Pos(':',S);
    if N > 0 then
    begin
      Response.Content:=Format('Username: %s<br>Password: %s',[Copy(S,1,N-1),Copy(S,N+1,Length(S)-N+1)]);
      Exit;
    end;
  end;
  Response.WWWAuthenticate := 'Basic';
  Response.StatusCode := 401;
end;
Klient:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  HTTP: TIdHTTP;
begin
  HTTP := TIdHTTP.Create;
  try
    HTTP.Request.BasicAuthentication := True;
    HTTP.HandleRedirects := True;
    HTTP.Request.Username := Edit1.Text;
    HTTP.Request.Password := Edit2.Text;
    Memo1.Lines.Text := StringReplace(HTTP.Get('http://maps4delphi.com/test'),'<br>',sLineBreak,[rfReplaceAll]);
  finally
    HTTP.Free;
  end;
end;
Damit reagiert der Server auch auf Browseranfragen (getestet mit IE9, IE10, Firefox und Google Chrome). Hier erscheint dann wegen des Statuscodes 401 der Eingabedialog für Name und Passwort.
Da ich den Zeilenumbruch in ein "<br>"-Tag umgewandelt habe, wird die Serverantwort auch korrekt im Browser angezeigt. Für die Anzeige im Delphi-Programm wird der Zeilenumbruch durch StringReplace umgewandelt.

Die Übergabe per "Name:Passwort@xyz" funktioniert nicht.

Unter Delphi 7 könnte es eventuell noch Probleme mit der Eigenschaft Request.Authorization geben. Das kann ich momentan leider nicht testen. Du könntest aber mal versuchen, diesen Wert direkt abzufragen:
Request.GetFieldByName('Authorization');

P.S.:
Das Ganze funktioniert natürlich auch über HTTPS (wegen Basic-Authentifikation = unsicher):
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  HTTP: TIdHTTP;
  SSL: TIdSSLIOHandlerSocketOpenSSL;
begin
  HTTP := TIdHTTP.Create;
  try
    SSL := TIdSSLIOHandlerSocketOpenSSL.Create;
    try
      HTTP.IOHandler := SSL;
      HTTP.Request.BasicAuthentication := True;
      HTTP.HandleRedirects := True;
      HTTP.Request.Username := Edit1.Text;
      HTTP.Request.Password := Edit2.Text;
      Memo1.Lines.Text := StringReplace(HTTP.Get('https://maps4delphi.com/test'),'<br>',sLineBreak,[rfReplaceAll]);
    finally
      SSL.Free;
    end;
  finally
    HTTP.Free;
  end;
end;
Thomas Nitzschke
Google Maps mit Delphi

Geändert von Thom ( 9. Apr 2013 um 20:19 Uhr)
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#12

AW: Anmelden an Webmodul über IdHTTP

  Alt 9. Apr 2013, 23:22
Hallo Thom,

Code:
http://username:password@maps4delphi.com/test
funktioniert mit dem Firefox, der IE unterstützt dies nicht.

Request.GetFieldByName('Authorization') liefert mir unter Delphi 7 keinen Wert. Da könnte also ein versionsabhängiges Problem vorliegen.
  Mit Zitat antworten Zitat
Thom

Registriert seit: 19. Mai 2006
570 Beiträge
 
Delphi XE3 Professional
 
#13

AW: Anmelden an Webmodul über IdHTTP

  Alt 10. Apr 2013, 01:00
Hallo Stephan,

wieder was dazu gelernt - danke! Mit dem Feuerfuchs funktioniert das tatsächlich.

Ich werde morgen (oder besser: heute) mal Delphi 7 auf dem Server installieren und die Sache testen. Vielleicht finden wir ja die Ursache für das Problem...
Thomas Nitzschke
Google Maps mit Delphi
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#14

AW: Anmelden an Webmodul über IdHTTP

  Alt 10. Apr 2013, 12:25
Hallo,

habe mal "weiter gedaddelt"

In meinem (mit Delphi 7 geschriebenen) Webserver kann ich die Anmeldedaten in RequestInfo.AuthUsername und RequestInfo.AuthPassword finden.

RequestInfo ist vom Typ TIdHTTPRequestInfo abgeleitet von TIdRequestHeaderInfo.

RequestInfo wird an die ISAPI.dlls weitergegeben und steht dort als Request vom Type TWebRequest zur Verfügung.

Die Attribute von RequestInfo auf Serverseite und Request auf DLL-Seite sind aber nicht identisch, es gibt lediglich eine Schnittmenge, welche Username und Password nicht enthält.

Momentan sehe ich keine Lösungsmöglichkeit für dieses Problem.
  Mit Zitat antworten Zitat
Thom

Registriert seit: 19. Mai 2006
570 Beiträge
 
Delphi XE3 Professional
 
#15

AW: Anmelden an Webmodul über IdHTTP

  Alt 10. Apr 2013, 13:09
Ich habe die Methode Test mal etwas abgewandelt:
Delphi-Quellcode:
procedure TWebModule1.WebModule1TestAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
var
  N: Integer;
  S: String;
begin
  S := String(Request.Authorization);
  N := Pos(' ',S);
  if N > 0 then
  begin
    Delete(S,1,N);
    S := TIdDecoderMIME.DecodeString(s);
    N := Pos(':',S);
    if N > 0 then
    begin
      Response.Content:=Request.GetFieldByName('ALL_RAW');
      Exit;
    end;
  end;
  Response.WWWAuthenticate := 'Basic';
  Response.StatusCode := 401;
end;
Damit wird jetzt der komplette Header, der vom Browser an den Server übertragen wird, angezeigt:
Code:
Connection: Keep-Alive
Content-Length: 0
Accept: text/html, application/xhtml+xml, */*
Accept-Encoding: gzip, deflate
Accept-Language: de-DE
Authorization: Basic VGVzdDpCbHVi
Cookie: [...]
Host: maps4delphi.com
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
X-Original-URL: /test
Hier kann man schön sehen, daß die Anmeldedaten wirklich im Wert "Authorization" enthalten sind.
Funktioniert das bei Dir in der Delphi 7 Dll?
Thomas Nitzschke
Google Maps mit Delphi
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#16

AW: Anmelden an Webmodul über IdHTTP

  Alt 10. Apr 2013, 14:38
Hallo Thom,

nö, funktioniert nicht.

Der Datenaustausch zwischen Webserver und DLL erfolgt über den TEXTENSION_CONTROL_BLOCK. In Delphi 7 ist er so definiert:
Delphi-Quellcode:
 TEXTENSION_CONTROL_BLOCK = packed record
    cbSize: DWORD; // size of this struct.
    dwVersion: DWORD; // version info of this spec
    ConnID: HCONN; // Context number not to be modified!
    dwHttpStatusCode: DWORD; // HTTP Status code
             // null terminated log info specific to this Extension DLL
    lpszLogData: array [0..HSE_LOG_BUFFER_LEN-1] of Char;
    lpszMethod: PChar; // REQUEST_METHOD
    lpszQueryString: PChar; // QUERY_STRING
    lpszPathInfo: PChar; // PATH_INFO
    lpszPathTranslated: PChar; // PATH_TRANSLATED
    cbTotalBytes: DWORD; // Total bytes indicated from client
    cbAvailable: DWORD; // Available number of bytes
    lpbData: Pointer; // pointer to cbAvailable bytes
    lpszContentType: PChar; // Content type of client data

    GetServerVariable: TGetServerVariableProc;
    WriteClient: TWriteClientProc;
    ReadClient: TReadClientProc;
    ServerSupportFunction: TServerSupportFunctionProc;
  end;
Zu finden in der \source\rtl\win\Isapi2.pas.

Die Werte aus diesem Block werden letztlich mit dieser Routine gelesen:
Delphi-Quellcode:
function TISAPIRequest.GetStringVariable(Index: Integer): string;
begin
  case Index of
    0: Result := ECB.lpszMethod;
    3: Result := ECB.lpszQueryString;
    4: Result := ECB.lpszPathInfo;
    5: Result := ECB.lpszPathTranslated;
    1..2, 6..24, 26..28: Result := GetFieldByName(ServerVariables[Index]);
    25: if ECB.cbAvailable > 0 then
      SetString(Result, PChar(ECB.lpbData), ECB.cbAvailable);
   else
      Result := '';
  end;
end;
Die möglichen, zu lesenden Werte sind:
Delphi-Quellcode:
const
  ServerVariables: array[0..28] of string = (
    '',
    'SERVER_PROTOCOL',
    'URL',
    '',
    '',
    '',
    'HTTP_CACHE_CONTROL',
    'HTTP_DATE',
    'HTTP_ACCEPT',
    'HTTP_FROM',
    'HTTP_HOST',
    'HTTP_IF_MODIFIED_SINCE',
    'HTTP_REFERER',
    'HTTP_USER_AGENT',
    'HTTP_CONTENT_ENCODING',
    'CONTENT_TYPE',
    'CONTENT_LENGTH',
    'HTTP_CONTENT_VERSION',
    'HTTP_DERIVED_FROM',
    'HTTP_EXPIRES',
    'HTTP_TITLE',
    'REMOTE_ADDR',
    'REMOTE_HOST',
    'SCRIPT_NAME',
    'SERVER_PORT',
    '',
    'HTTP_CONNECTION',
    'HTTP_COOKIE',
    'HTTP_AUTHORIZATION');
Es ist mir bisher nicht gelungen, an andere Werte zu kommen.

Ist dieser Kommentar aus der Isapi2.pas eventuell von Bedeutung?
Delphi-Quellcode:
{       Structure definitions and prototypes for the    }
{       version 2.0 HTTP Server Extension interface.    }
Sprich: Hat sich da in der Version was verändert?

Irgendwie weiß ich momentan nicht weiter. Die Anmeldedaten sind in einer DLL wohl sehr geheim
  Mit Zitat antworten Zitat
Thom

Registriert seit: 19. Mai 2006
570 Beiträge
 
Delphi XE3 Professional
 
#17

AW: Anmelden an Webmodul über IdHTTP

  Alt 10. Apr 2013, 16:21
Wahrscheinlich...

Ich habe jetzt nach etlichen Mühen Delphi 7 unter Windows Server 2008 zum Laufen bekommen. Dummerweise akzeptiert der IIS nur 32- oder 64Bit Dll's, so daß ich den ganzen Rest auch noch mal "schnell" nach 32Bit umsetzen mußte.

Die gute Nachricht: Die Anmeldung funktioniert auch mit einer ISAPI-Dll, die mit Delphi 7 kompiliert wurde. Das kannst Du hier testen.

Die schlechte Nachricht: Ich habe momentan absolut keine Idee, weshalb das bei Dir nicht funktioniert.
Könntest Du eventuell mal Deine Dll (Quelltext) hier posten, damit ich die bei mir ausprobieren kann?
Thomas Nitzschke
Google Maps mit Delphi
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#18

AW: Anmelden an Webmodul über IdHTTP

  Alt 10. Apr 2013, 17:40
Hallo Thom,

Quelltext und kompilierte DLL als Zip.
Die DLL ist kein Meisterwerk in objektorientierter oder sauberer Programmierung, sondern so dahingedaddelt und teilweise aus Textlisten generiert. Tut halt

Könnte es sein, dass unterschiedliche Webserver hier die Daten nach "gutdünken" weitergeben?

Nach weiterem Suchen in diversen Quelltexten habe ich herausgefunden, dass ich bei meinem Webserver und meiner DLL den Benutzernamen in der Servervariabel AUTH_NAME und das Passwort in AUTH_PASS finden kann. Ob das aber immer so ist oder so sein muss, kann ich nicht sagen.

Würde mich schon interessieren, ob Du mit dieser DLL die Werte an den gleichen Stellen bekommst oder das mit dem IIS alles irgendwie anders ist. Dann muss ich in meinem Webserver nämlich wohl doch noch ein paar Fehler beheben

Geändert von nahpets (21. Nov 2017 um 16:41 Uhr)
  Mit Zitat antworten Zitat
Thom

Registriert seit: 19. Mai 2006
570 Beiträge
 
Delphi XE3 Professional
 
#19

AW: Anmelden an Webmodul über IdHTTP

  Alt 10. Apr 2013, 20:54
Hallo Stephan,

ändere mal im Quelltext folgenden Abschnitt:
Delphi-Quellcode:
  [...]
  if N > 0 then begin
    Delete(S,1,n);
    S := TIdDecoderMIME.DecodeString(S);
    N := Pos(':',S);
    if N > 0 then begin
      sAuthorization := Format('Username: %s'+ sLineBreak +'Password: %s',[Copy(S,1,N-1),Copy(S,N+1,Length(S)-N+1)]);
    end;
  end else //<- ab hier zusätzlich
  begin
    Response.WWWAuthenticate := 'Basic';
    Response.StatusCode := 401;
    Exit;
  end;
  [...]
Ansonsten fordert der Server keine Autorisation an und damit wird diese auch nicht angezeigt. Im Feuerfuchs funktioniert das auch mit Username:Password@xyz.

P.S.: Test hier.
Thomas Nitzschke
Google Maps mit Delphi
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#20

AW: Anmelden an Webmodul über IdHTTP

  Alt 10. Apr 2013, 23:06
Hallo Thom,

Danke für die viele Mühe die Du Dir bei der Probelmlösung machst.

Auf dem IIS hast Du quasi meine DLL eingebunden, die Ergebnisseite ist bei Dir deutlich "besser" mit Informationen gefüllt, als bei mir. D. h.: Mein Webserver gibt (warum auch immer) nicht alle Informationen preis. Da ich für das ganze nur die Indy-Komponenten sowie idRunner components v. 3.4 nutze, muss ich die Ursache (vermutlich) dort irgendwo suchen oder eine Stelle finden, an der ich die Informationen gezielt "einstreuen" kann.

Die Änderung an der DLL bringt bei mir keinen Vorteil, im Gegenteil, die Methode wird immer im neuen Else-Zweig verlassen, so dass ich nie ein Ergebnis zu Gesicht bekomme. Der Webserver fordert aber die Anmeldung an und protokolliert die erfolgreiche Anmeldung.

Das sieht im Protokoll dann so aus:
Code:

HTTPServer | 2013.04.10 23.49.45,453 | 127.000.000.001:4068 | stephan | GET /scripts/webmodul.dll/request
HTTPServer | 2013.04.10 23.49.45,453 | 127.000.000.001 | localhost | erlaubter Zugriff mit IP-Security
HTTPServer | 2013.04.10 23.49.45,500 | Login ok | Benutzername: stephan
HTTPServer | 2013.04.10 23.49.45,625 | 127.000.000.001:4068 | stephan | GET .\scripts\webmodul.dll | 4375 | 200 | text/html
Da mein Webserver nicht aus der großen weiten Welt zu sehen ist, sondern nur lokal genutzt wird, habe ich mal die Ergebnisseite, wie sie sich hier darstellt, drangehängt.

Geändert von nahpets (21. Nov 2017 um 16:41 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:56 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz