TS: MySQL Trusted Login

Hello,

ich hoffe, die Datenbank- und API-Strategen können mir weiterhelfen.

Ich möchte ein trusted Login für die PHP-MySQL-Connection bauen (oder eine fertige Lösung finden).

Üblicherweise benutzen PHP-Lösungen für die Connection zur MySQL-Datenbank immer eine ihnen bekannte Benutzer-Passwort-Kombination. Das bedeutet also, dass der API ein (oder mehrere) User mit dem dazugehörigen Passwort bekannt sind.

Mehrere DB-API-User benötigt man, um unterschiedliche Rechte abbilden zu können.
Beispiele:

  • normaler Seitenbesucher ohne Account (API-Basisaccount)
  • Seitenbesucher mit Account -- darf nur seine Dokumente bearbeiten -- darf auch Dokumente Anderer bearbeiten -- ...
  • Moderator, Redakteur, Content-Bearbeiter
  • Gruppenleiter
  • Admin
  • Superadmin

Die Rollen bilden sich in vertikalen Rechten in den Tabellen ab.

Ich möchte die Abbildung dieser Geschäftsregeln nun mittels Stored Routines und Triggers vollständig in die Datenbank verlegen. Das bedeutet, dass die API keine n Zugriff mehr auf die rollenspezifischen Credentials haben darf. Die API-Funktion für ein Login darf nur noch Zugang zu den Basis-Selects geben.

Um eine höherwertige Rolle zu erwerben, benötigt man ein granted Select für den API-User, der die Rechte des jeweiligen externen Users erfragt und in der DB-Schnittstelle zwischenspeichert. Die API bekommt nur noch einen Trustie-Datensatz zurück. Mit diesem kann sie sich dann gezielt eine zweite Connection beschaffen, deren DB-User über die passenden Rechte verfügt, um mittels der Stored Routines dann die vertikalen Durchgriffe zu realisieren.

#Nur zwei Fragen

  • denke ich da zu kompliziert; wie würde man es besser lösen?
  • wie würde ich anderenfalls die Trustie-Records erzeugen und verwalten können? Die müssen ja auch irgendwann wieder verfallen, am liebsten nur requestbasiert gelten und nicht pro Session. Aber das würde die DB-Aktion enorm in die Höhe treiben.
    (Ist ja aber bei TLS auch nicht anders. Das Token gilt immer nur für einen Request.)

Liebe Grüße
Tom S.

--
Es gibt nichts Gutes, außer man tut es!
Das Leben selbst ist der Sinn.
  1. Hallo TS,

    mir ist nicht ganz klar, wie diese Rechteerhöhung funktionieren soll. Der DB-Server kann dem Web-Server keine "besonders berechtigte Connection" geben. Der Web-Server kann eine aufbauen, braucht dafür aber passende Credentials. Hier mit Wegwerf-Credentials und Einmal-Grants zu arbeiten dürfte den SQL Server in die Knie zwingen. Wenn Du dem Webserver nur Basis-Credentials geben willst, darfst Du keinen einzigen INSERT/UPDATE/DELETE mehr an den technischen User des Frontend granten, sondern nur noch SELECTS und das Recht, bestimmte Routinen auszuführen. Diese übernehmen dann alle Datenzugriffe und prüfen die Berechtigungen dazu. Im Extremfall musst Du sogar die SELECTs in Routinen legen. Du bekommst jetzt aber ein Problem:

    • ein SQL Server ist stateless, d.h. er kann nicht speichern, dass sich ein User X erfolgreich authentifiziert hat. Du musst also entweder bei jedem Zugriff User-ID und Passwort mitgeben, oder über eine Authentication Routine eine Session-ID erzeugen und die in einer Session-Table halten. Die Session-Prüfung baust Du in jeder einzelne Routine ein, die Du in den DB-Server legst. Lass das!

    • die Alternative wäre, dass deine externen User im SQL Server als User angelegt sind und die DB-Connection mit den Credentials dieser User aufgebaut wird. Das führt zu einer komplexen Userverwaltung, die bei Anlage eines neuen Users für das Web-Frontend auch einen DB-User anlegen muss. Nein!!

    Ich würde zu einer klareren Trennung der Zuständigkeiten raten. Es geht Dir vermutlich darum, zu verhindern, dass ein kompromittierter Webserver auf der DB herumtoben kann.

    Für so etwas trennt man die einfache 2-Tier Architektur (Server für HTML-Rendering und Logik / DB-Server) in eine 3-Tier Architektur auf (Web-Server / Application-Server / DB-Server). Der Web Server kümmert sich in diesem Modell um das HTML Rendering und ist auf fachlicher Ebene Durchlauferhitzer. Der Application Server enthält die Geschäftslogik und insbesondere auch die Rechtesteuerung. Rollenspezifische Rechte sind Geschäftslogik.

    Ein DB Server soll sich mMn generell nicht um userspezifische Rechte und Geschäftslogik kümmern, sondern nur um eine möglichst flotte Bereitstellung der Daten. Abfragen in Routinen zu kombinieren macht aus meiner Sicht nur Sinn, wenn man Tabellendaten auf eine Weise miteinander kombinieren muss, die mit SQL nicht darstellbar ist und eine Auswertung auf dem Web-/App-Server zuviele unnütze Daten aus dem SQL Server lesen müsste. Ein DB-Server darf auch noch technische Rechte bewachen (d.h. verhindern, dass die Application B die Tabellen der Application A umpflügt - dafür der technische User).

    Ein paar Ansätze zum Gebrauch:

    Wenn sich ein User am Webserver anmeldet, führt der Webserver das nicht selbst durch. Statt dessen beauftragt er den App-Server mit der Authentication und erhält eine Session-ID auf dem App-Server. Die kommt wie üblich in den Cookie für den Anwender, und damit braucht der WEB Server keine eigene Sessionverwaltung mehr. Und er muss auch keine DB-Credentials kennen.

    Der App-Server verwaltet User-Sessions, cached dort ggf. ermittelte Rollenrechte und spuckt jedesmal Gift und Schwefel, wenn der Webserver mit der Session des Users X eine Operation durchführen will, die für X nicht erlaubt ist.

    Die weitere Vorgehensweise ist dann noch, zwischen Web-Server und App-Server eine Firewall zu platzieren, so dass der Application-Server vom Browser des Users aus netzwerktechnisch überhaupt nicht erreichbar ist. Der Netzwerkteil, in dem der Webserver steht, wird dann DMZ genannt (Ja. Genau. Demilitarisierte Zone).

    Vorteil des Ganzen ist auch, dass es besser skaliert. Wenn deine Application Logik aufwändig ist und der App-Server zu dampfen beginnt, ersetzt Du ihn durch einen Cluster. Wenn die Application Logik eher dürftig ist, man aber dafür auf dem Webserver in der DMZ Popcorn rösten kann, dann clusterst Du den. Wenn Du der Meinung bist, deine Application Logik statt in PHP besser/performanter in Java oder C# darstellen zu können, dann ersetzt Du die Appserver-Scripte durch Services in Java, C# oder C++.

    Rolf

    --
    sumpsi - posui - clusi
    1. Hello,

      nur als Kurzantwort auf diesen Passus:

      • die Alternative wäre, dass deine externen User im SQL Server als User angelegt sind und die DB-Connection mit den Credentials dieser User aufgebaut wird. Das führt zu einer komplexen Userverwaltung, die bei Anlage eines neuen Users für das Web-Frontend auch einen DB-User anlegen muss. Nein!!

      Das primäre Backend des Web-Frontends benötigt dann keine Anmeldung mehr. Jeder darf es benutzen. Aber wenn er mehr will, als es der "World-Account" darf, muss er sich anmelden. Diese Anmeldung wird dann mit den Credentials des Frontendusers oder seinem Token an die DB weitergereicht. Die entscheidet dann aufgrund der Rollentabelle oder sonstiger, auf welchen DB-User umgeschaltet werden darf.

      Leider finde ich die Funktionen für den Benutzerwechsel innerhalb MySQL nicht mehr.

      Entweder habe ich die damals nur geträumt, oder sie sind abgeschaft, oder ich bin zu blind, sie in den neueren Dokus zu finden... (oder...)

      Liebe Grüße
      Tom S.

      --
      Es gibt nichts Gutes, außer man tut es!
      Das Leben selbst ist der Sinn.