AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Delphi Kerberos für SOAP per WSDL Import
Thema durchsuchen
Ansicht
Themen-Optionen

Kerberos für SOAP per WSDL Import

Ein Thema von Sherlock · begonnen am 27. Feb 2015 · letzter Beitrag vom 25. Jul 2021
 
Benutzerbild von Sherlock
Sherlock

Registriert seit: 10. Jan 2006
Ort: Offenbach
3.821 Beiträge
 
Delphi 12 Athens
 
#6

AW: Kerberos für SOAP per WSDL Import

  Alt 5. Mär 2015, 15:08
Sodele, ich würde das hier gerne weiterspinnen. Meine Recherchen im Netz führen mich zu der Erkenntnis, daß es niemanden gibt, der bereits erfolgreich mit Delphi in OS ein Kerberos Ticket angefordert hat. Alle verweisen auf die üblichen Verdächtigen, die bei SO, oder eben der msdn verlinkt sind. Knackpunkt ist folgendes:
Es ist eben nicht damit getan ein paar API-Funktionen aufzurufen. Ein Kerberos-Ticket muss man sich auch per UDP-Kommunikation mit dem Kerberos-Server verdienen. Das führt dazu, daß selbst die zahlreichen voneinander abgeschrieben Beispile in den C-Dialekten an der Stelle äusserst schwammig werden. Ich halte Kerberos mittlerweile für eine Art weissen Wal, den jeder angeblich mal gesehen hat

Die API-Aufrufe bekommt man mit Hilfe von ein bis zwei Indy-Units einigermaßen zusammengeklöppelt. Aber selbst dann muss der korrekte SPN von Aussen gesetzt werden, Es gibt keine API, die einem das abnimmt. Hier die Source meines kleinen Testprojekts:

Delphi-Quellcode:
uses IdSSPI, IdAuthenticationSSPI

procedure TForm2.Button1Click(Sender: TObject);
var
  secfunc: SecurityFunctionTableA;
  sec_Entry: SECURITY_STATUS;
  pszTargetName: PSEC_CHAR;
  hCredential: SecHandle;
  tsExpiry: TimeStamp;
  hNewContext: CtxtHandle;
  Output: SecBufferDesc;
  token: SecBuffer;
  fContextAttr: ULONG;
  pPkgInfo: PSecPkgInfoA;
  TokenPointer: PByteArray;
  InitSecurityInterfaceA: function: PSecurityFunctionTableA; stdcall;
begin
  try
    TokenPointer := nil;
    InitSecurityInterfaceA := GetProcAddress(GetModuleHandle('secur32.dll'), 'InitSecurityInterfaceA');
    if Assigned(InitSecurityInterfaceA) then
      secfunc := InitSecurityInterfaceA^;

    sec_State:= secfunc.QuerySecurityPackageInfoA(
      PAnsiChar('Kerberos'),
      @pPkgInfo
      );

    if sec_State = SEC_E_OK then
      sec_State := secfunc.AcquireCredentialsHandleA(
        nil,
        pPkgInfo^.Name,
        SECPKG_CRED_OUTBOUND,
        nil,
        nil,
        nil,
        nil,
        @hCredential,
        @tsExpiry
        );

    Output.ulVersion := SECBUFFER_VERSION;
    Output.cBuffers := 1;
    Output.pBuffers := @token;

    GetMem(TokenPointer, ppkginfo^.cbMaxToken);

    token.cbBuffer := ppkginfo^.cbMaxToken;
    token.BufferType := SECBUFFER_TOKEN;
    token.pvBuffer := tokenpointer;

    if sec_State = SEC_E_OK then
      sec_State := secfunc.InitializeSecurityContextA(
        @hCredential,
        nil,
        PAnsiChar('RestrictedKrbHost/FM-DC01.mydomain.int'), // Muss man eben irgendwie selbst herausfinden
        ISC_REQ_DELEGATE + ISC_REQ_MUTUAL_AUTH,
        0,
        SECURITY_NATIVE_DREP,
        nil,
        0,
        @hNewContext,
        @Output,
        @fContextAttr,
        @tsExpiry
        );

    if sec_State = SEC_I_CONTINUE_NEEDED then // Derzeit ist genau das der Status
    begin
      // Output irgendwie an den Kerberos-Server senden und die Anwort mit erneutem Aufruf von
      // InitializeSecurityContextA verwursten
    end;

    if sec_State = SEC_E_OK then
    begin
      ShowMessage('YAY!');
    end
    else
      case sec_State of
        SEC_E_OK: ShowMessage('YAY!');
        SEC_I_COMPLETE_AND_CONTINUE: ShowMessage('SEC_I_COMPLETE_AND_CONTINUE');
        SEC_I_COMPLETE_NEEDED: ShowMessage('SEC_I_COMPLETE_NEEDED');
        SEC_I_CONTINUE_NEEDED: ShowMessage('SEC_I_CONTINUE_NEEDED');
        SEC_I_INCOMPLETE_CREDENTIALS: ShowMessage('SEC_I_INCOMPLETE_CREDENTIALS');
        SEC_E_INSUFFICIENT_MEMORY: ShowMessage('SEC_E_INSUFFICIENT_MEMORY');
        SEC_E_INTERNAL_ERROR: ShowMessage('SEC_E_INTERNAL_ERROR');
        SEC_E_INVALID_HANDLE: ShowMessage('SEC_E_INVALID_HANDLE');
        SEC_E_INVALID_TOKEN: ShowMessage('SEC_E_INVALID_TOKEN');
        SEC_E_LOGON_DENIED: ShowMessage('SEC_E_LOGON_DENIED');
        SEC_E_NO_AUTHENTICATING_AUTHORITY: ShowMessage('SEC_E_NO_AUTHENTICATING_AUTHORITY');
        SEC_E_NO_CREDENTIALS: ShowMessage('SEC_E_NO_CREDENTIALS');
        SEC_E_TARGET_UNKNOWN: ShowMessage('SEC_E_TARGET_UNKNOWN');
        SEC_E_UNSUPPORTED_FUNCTION: ShowMessage('SEC_E_UNSUPPORTED_FUNCTION');
        SEC_E_WRONG_PRINCIPAL: ShowMessage('SEC_E_WRONG_PRINCIPAL');
      else
        ShowMessage('UNKNOWN ERROR Code. Last Error:' + IntToStr(GetLastError));
      end;
  finally
    secfunc.FreeCredentialsHandle(@hCredential);
    secfunc.FreeContextBuffer(pPkgInfo);
    FreeMem(TokenPointer);
  end;
end;
Wer hat sowas mal wirklich vollumfänglich implementiert? (Der SOAP-Teil aus meinem Startpost kann erstmal getrost vergessen werden)

Sherlock
Oliver
Geändert von Sherlock (Morgen um 16:78 Uhr) Grund: Weil ich es kann
  Mit Zitat antworten Zitat
 

 

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 18:07 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz