Bachelorarbeit FAKULTÄT INFORMATIK - Johannes Steinleitner Betreueung: Prof. Dr.-Ing. Johann Uhrmann, Hochschule Landshut - OPUS 4

Die Seite wird erstellt Dörte Prinz
 
WEITER LESEN
FAKULTÄT INFORMATIK

                 Bachelorarbeit

Verteilte Policy-basierte Autorisierung mit OAuth 2.0
                 und OpenID Connect

                  Johannes Steinleitner

                        Betreueung:
     Prof. Dr.-Ing. Johann Uhrmann, Hochschule Landshut
               Christian Fritz, QAware GmbH
ERKLÄRUNG ZUR BACHELORARBEIT

                              Steinleitner, Johannes

                     Hochschule Landshut
                          Fakultät Informatik

 Hiermit erkläre ich, dass ich die Arbeit selbständig verfasst, noch
nicht anderweitig für Prüfungszwecke vorgelegt, keine anderen als
die angegebenen Quellen oder Hilfsmittel benützt, sowie wörtliche
     und sinngemäße Zitate als solche gekennzeichnet habe.

       ....................               ....................................................
      (Datum)                            (Unterschrift des Studierenden)
Zusammenfassung/Abstract

Durch den Open Policy Agent (OPA) soll es eine einheitliche Lösung geben, um Policy
Entscheidungen für unterschiedlichste Anwendungen im Cloud-Native-Umfeld durchzu-
setzen. [OPA20e] Es gibt schon viele Projekte, die OPA integriert haben. Hierzu zählen
das AWS API Gateway, um den API Datenverkehr zu kontrollieren, Kubernetes um die
Ressourcen Nutzung zu begrenzen. [OPA20d] Ein weiterer Anwendungsfall ist in Micro-
services als Sidecar um eine verteilte Autorisierung zu ermöglichen. Durch OPA können
die Policies von den Services getrennt werden. Somit müssen Services nicht neu deployt
werden, falls sich die Policies ändern. [OPA20e] OPA hat jedoch keine eingebaute Funktion
für die Authentifizierung und das Identitätsmanagement. [OPA20a] In dieser Arbeit soll
aufgezeigt werden, wie die Authentifizierung mithilfe von Keycloak und die Autorisierung
mit dem Open Policy Agent umgesetzt werden kann.
Inhaltsverzeichnis                                                                          1

Inhaltsverzeichnis
1 Einleitung                                                                               4
   1.1   Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .     4
   1.2   Ziele . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .    5
   1.3   Aufbau . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .     5

2 Grundlagen                                                                               6
   2.1   Informationssicherheit . . . . . . . . . . . . . . . . . . . . . . . . . . .       6
         2.1.1   Schutzziele . . . . . . . . . . . . . . . . . . . . . . . . . . . . .      6
         2.1.2   Authentifizierung und Autorisierung . . . . . . . . . . . . . .            7
   2.2   Identity und Access Management . . . . . . . . . . . . . . . . . . . . .           8
   2.3   Zugriffskontrolle (engl. Access Control) . . . . . . . . . . . . . . . . .         8
         2.3.1   Role Based Access Control . . . . . . . . . . . . . . . . . . . . .        8
         2.3.2   Attribute Based Access Control . . . . . . . . . . . . . . . . . .        10
         2.3.3   Vergleich RBAC und ABAC . . . . . . . . . . . . . . . . . . . .           11
         2.3.4   Kombination von RBAC und ABAC . . . . . . . . . . . . . . .               11
   2.4   JSON Web Token . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .        12
         2.4.1   Aufbau . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .    12
   2.5   OAuth 2.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .     14
         2.5.1   Grundbegriffe . . . . . . . . . . . . . . . . . . . . . . . . . . . .     15
         2.5.2   Flows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   16
                 2.5.2.1   Authorization Code Flow . . . . . . . . . . . . . . . .         17
                 2.5.2.2   Authorization Code Flow with PKCE . . . . . . . . .             18
                 2.5.2.3   Client Credentials Flow . . . . . . . . . . . . . . . . .       20
                 2.5.2.4   Token Exchange Flow . . . . . . . . . . . . . . . . . .         21
   2.6   OpenID Connect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .        22
         2.6.1   Authorization Code Flow . . . . . . . . . . . . . . . . . . . . .         23
   2.7   Microservices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .     24
         2.7.1   Vorteile gegenüber eines Monolithen . . . . . . . . . . . . . .           24
         2.7.2   Sidecar-Muster . . . . . . . . . . . . . . . . . . . . . . . . . . .      25
Inhaltsverzeichnis                                                                           2

   2.8   CAP-Theorem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .        25

3 Fachliche Anforderungen                                                                   27
   3.1   Authentifizierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .      27
         3.1.1   Unterstützung von OpenID Connect . . . . . . . . . . . . . . .             27
   3.2   Autorisierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .      27
         3.2.1   Lesbarkeit der Policies . . . . . . . . . . . . . . . . . . . . . . .      27
         3.2.2   Austauschbarkeit der Policies . . . . . . . . . . . . . . . . . . .        27
         3.2.3   Testbarkeit der Policies . . . . . . . . . . . . . . . . . . . . . . .     28
         3.2.4   Plattformunabhängigkeit . . . . . . . . . . . . . . . . . . . . .          28
         3.2.5   Performance . . . . . . . . . . . . . . . . . . . . . . . . . . . . .      28
         3.2.6   Verteilte Autorisierung . . . . . . . . . . . . . . . . . . . . . . .      28

4 Technisches Konzept                                                                       29
   4.1   Verwendete Technologien . . . . . . . . . . . . . . . . . . . . . . . . .          29
         4.1.1   Open Policy Agent . . . . . . . . . . . . . . . . . . . . . . . . .        29
                 4.1.1.1   Rego . . . . . . . . . . . . . . . . . . . . . . . . . . . .     30
                 4.1.1.2   Filtern von Daten . . . . . . . . . . . . . . . . . . . .        32
                 4.1.1.3   Bundles . . . . . . . . . . . . . . . . . . . . . . . . . .      34
         4.1.2   Keycloak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .     34
         4.1.3   Kubernetes . . . . . . . . . . . . . . . . . . . . . . . . . . . . .       35
         4.1.4   Google Kubernetes Engine . . . . . . . . . . . . . . . . . . . .           35
         4.1.5   Google Cloud Storage . . . . . . . . . . . . . . . . . . . . . . .         35
   4.2   Architektur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .    36

5 Implementierung                                                                           38
   5.1   Aufbau der Beispielanwendung . . . . . . . . . . . . . . . . . . . . . .           38
         5.1.1   Regeln für die Autorisierung . . . . . . . . . . . . . . . . . . .         39
   5.2   Microservices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .      41
         5.2.1   Autorisierung . . . . . . . . . . . . . . . . . . . . . . . . . . . .      41
         5.2.2   Datenfilterung . . . . . . . . . . . . . . . . . . . . . . . . . . . .     43
   5.3   Keycloak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .     44
   5.4   Open Policy Agent . . . . . . . . . . . . . . . . . . . . . . . . . . . . .        45
         5.4.1   Policies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   45
         5.4.2   Bundles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .      49
   5.5   Kubernetes Deployment . . . . . . . . . . . . . . . . . . . . . . . . . .          51
   5.6   Frontend . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .     52
Inhaltsverzeichnis                                                                            3

6 Ergebnis                                                                                   53
   6.1   Fazit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   53
   6.2   Ausblick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .      54

Literaturverzeichnis                                                                         55

Anhang                                                                                       59

Abbildungsverzeichnis                                                                        70

Tabellenverzeichnis                                                                          71

Listings                                                                                     72

Akronyme                                                                                     74
1 Einleitung                                                                       4

1 Einleitung
In diesem Kapitel werden die Motivation, sowie der Aufbau und die Ziele von
dieser Arbeit aufgezeigt.

1.1 Motivation
Viele Unternehmen nutzen zur Sicherheit ihres Netzwerkes eine demilitarisierte
Zone (DMZ). Es handelt sich um einen Bereich, der außerhalb des geschützten
Unternehmensnetzwerkes liegt. Diese Zone stellt die Verbindung zwischen den
internen Ressourcen, die im Internet verfügbar sein sollen, und dem öffentlichen
Netzwerk dar. Typische Anwendungen, auf die von außerhalb des Netzwerkes
zugegriffen werden soll, sind die E-Mail und VPN Server. Der Datenverkehr wird
durch die DMZ gefiltert. Das soll gefährliche Anfragen z. B. durch eine Firewall
herausfiltern. [Web14] In diesem Modell wird dem Datenverkehr innerhalb des
Netzwerkes vertraut. Hat es ein Angreifer geschafft, die DMZ zu überwinden ist es
für diesen relativ einfach auf vertrauliche Daten des Unternehmens zuzugreifen.
Das Modell funktioniert, wenn alle innerhalb des Unternehmens arbeiten. Dies
ist aber in der heutigen Zeit nicht mehr voraussetzbar. Mitarbeiter möchte auch
von Zuhause oder von Unterwegs arbeiten können und auf die Daten, die sie
benötigen zugreifen. Es werden im Unternehmen auch immer mehr Cloud Dienste
eingesetzt, wodurch noch mehr Angriffsvektoren entstehen. [WB14] Deshalb wurde
in 2010 von Forrester Research das Prinzip Zero Trust eingeführt. Dieses Prinzip
besagt: Vertraue niemanden und verifiziere alles. Jeder Zugriff auf eine Ressource
muss authentifiziert und autorisiert erfolgen. Setzt man das Prinzip von Zero Trust
um, muss dies auch in den Microservices berücksichtigt werden. [Saw20] In dieser
Arbeit soll ein Aspekt des Zero-Trust-Prinzips, der verlangt, dass jeder Microservice
selbst eine Autorisierung vornimmt betrachtet werden.
1 Einleitung                                                                         5

1.2 Ziele
Ziel dieser Arbeit ist es aufzuzeigen, wie eine verteilte Autorisierung und Authen-
tifizierung mithilfe der Standards OAuth 2.0 und OpenID Connect in Microservices
umgesetzt werden kann. Dazu soll der Open Policy Agent (OPA) genutzt werden,
der viele der fachlichen Anforderungen, wie Plattformunabhängigkeit und Aus-
tauschbarkeit der Policies erfüllt. Auf diese Anforderungen wird näher in Kapitel
3 eingegangen. OPA hat jedoch keine eingebaute Funktion für Identitätsmanage-
ment und Authentifizierung. Hierfür soll Keycloak genutzt werden. Es soll nun
gezeigt werden wie die ausgestellten JSON Web Token (JWT) von Keycloak für
die Autorisierung in OPA genutzt werden können. Am Ende soll außerdem eine
Beispielanwendung mit diesem Konzept implementiert werden.

1.3 Aufbau
Die Bachelorarbeit ist in 6 Abschnitte aufgeteilt.
Im zweiten Kapitel werden die grundlegenden Konzepte für die Authentifizierung
und Autorisierung erklärt und Protokolle mit denen diese Umgesetzt werden kann
vorgestellt. Weiterhin werden die wichtigsten Begriffe zu Microservices erläutert.
Die fachlichen Anforderungen, die für die Authentifizierung und Autorisierung
gelten sollen folgen im dritten Kapitel.
Im vierten Teil werden die Technologien vorgestellt, die für die Umsetzung benötigt
werden. Besonders wichtig sind hierbei Keycloak und der Open Policy Agent.
Im fünften Kapitel wird ein Prototyp mit den Technologien aus dem vorherigen
Kapitel erstellt und in der Google Cloud implementiert.
Abschließend wird im letzten Kapitel noch ein Fazit gezogen und ein Ausblick auf
weitere mögliche Arbeiten gezeigt.
2 Grundlagen                                                                    6

2 Grundlagen
In diesem Kapitel geht es um die grundlegenden Begriffe in der Informationssi-
cherheit und der Identitätsverwaltung. Weiterhin werden die Protokolle für Au-
thentifizierung und Autorisierung OAuth und OpenID Connect erklärt. Am Ende
werden noch Grundlagen zu den Microservices erläutert.

2.1 Informationssicherheit
Informationen besitzen einen essenziellen Wert für Unternehmen und müssen des-
halb geschützt werden. Wenn diese nicht ausreichend geschützt werden handelt es
sich um ein Risiko, das die Existenz des Unternehmens bedrohen kann. [BSI20a]

2.1.1 Schutzziele
Der Zugriff auf Informationen darf nur von autorisierten Subjekten vorgenom-
men werden. Dies wird durch die Schutzziele Datenintegrität und Informations-
vertraulichkeit ausgedrückt. Zusätzlich dazu sollte das System sicherstellen, dass
der Zugriff auch möglich ist, wenn ein Benutzer autorisiert ist. Dies wird durch
das Schutzziel Verfügbarkeit sichergestellt. [Eck18, S.7f] Im nachfolgenden wer-
den diese 3 allgemeinen Schutzziele und die Authentizität, die zu den erweiterten
Schutzzielen zählt, vorgestellt.

Informationsvertraulichkeit:
„Wir sagen, dass das System die Informationsvertraulichkeit (engl. confidentia-
lity) gewährleistet, wenn es keine unautorisierte Informationsgewinnung ermög-
licht.“ [Eck18, S.10]
Dies bedeutet niemand hat Zugriff auf Information, für die er keine Berechtigungen
hat. Ein Beispiel ist eine Banking-App. Es sollte keiner außer dem Benutzer und
der Bank zugriff auf den Kontostand haben.
2 Grundlagen                                                                   7

Datenintegrität:
„Wir sagen, dass das System die Datenintegrität (engl. integrity) gewährleistet,
wenn es Subjekten nicht möglich ist, die zu schützenden Daten unautorisiert und
unbemerkt zu manipulieren.“ [Eck18, S.9]
Daten dürfen nur von Personen oder Programmen verändert, hinzugefügt oder
gelöscht werden, wenn diese eine Berechtigung dafür haben. Ein negatives Beispiel
wäre in diesem Fall eine Überweisung in einer Banking-App, bei der ein Angrei-
fer den Betrag ändern könnte, wenn die Überweisung zur Bank übertragen wird.
Hierfür muss nicht unbedingt auch die Informationsvertraulichkeit beeinträchtigt
sein. Der Angreifer muss nur genau wissen, wo der Betrag steht.

Verfügbarkeit:
„Wir sagen, dass das System die Verfügbarkeit (engl. availability) gewährleistet,
wenn authentifizierte und autorisierte Subjekte in der Wahrnehmung ihrer Berech-
tigungen nicht unautorisiert beeinträchtigt werden können.“ [Eck18, S.12]
Auf den ersten Blick hat Verfügbarkeit nicht viel mit IT-Sicherheit zu tun. Dabei
handelt es sich jedoch um ein sehr wichtiges Schutzziel. Den würde man dieses
weglassen, wäre ein sicheres System eines, das nicht mit dem Internet verbunden
ist und auch keinen physischen Zugriff ermöglicht. Das ergibt aber meistens wenig
Sinn.

Zusätzlich zu den 3 allgemeinen Schutzzielen werden weitere Schutzziele defi-
niert. Für diese Arbeit ist vor allem die Authentizität relevant.

Authentizität
„Unter der Authentizität eines Objekts bzw. Subjekts (engl. authenticity) verste-
hen wir die Echtheit und Glaubwürdigkeit des Objekts bzw. Subjekts, die an-
hand einer eindeutigen Identität und charakteristischen Eigenschaften überprüfbar
ist.“ [Eck18, S.8]
Damit die Authentizität sichergestellt werden kann, muss zuerst eine Authentifi-
zierung stattfinden. Diese wird im nächsten Absatz beschrieben.

2.1.2 Authentifizierung und Autorisierung
Durch die Authentifizierung wird die Authentizität eines Subjekts oder Objekts
überprüft. Hierfür muss nachgewiesen werden, dass es sich um die Identität eines
2 Grundlagen                                                                         8

Objekts oder Subjekts handelt, die er vorgibt zu sein. In vielen Fällen erfolgt die Au-
thentifizierung eines Nutzers durch einen Nutzernamen und ein Passwort. [Eck18,
S.8]

Bei der Autorisierung geht es hingegen darum, ob ein Subjekt berechtigt ist ei-
ne bestimmte Aktion durchzuführen. [BSI20b]
Das heißt bevor überhaupt eine Autorisierung durchgeführt werden kann, muss
zuvor eine Authentifizierung erfolgt sein.

2.2 Identity und Access Management
Identity und Access Management (IAM) ist in einem Unternehmen wichtig für
das Verwalten von Identitäten und die Zugriffsrechte auf die einzelnen Systeme.
Durch das IAM können einem Nutzer Berechtigungen zugewiesen werden, um eine
Aktion an einem System durchzuführen. Die wichtigsten Funktionen, die ein IAM
mit sich bringt, sind die Authentifizierung und die Autorisierung eines Nutzers.
Es gibt darüber hinaus noch weitere wichtige Funktionen wie Single Sign-On,
wodurch ein Nutzer mit einer Identität auf mehrere Systeme zugreifen kann. [LS17]

2.3 Zugriffskontrolle (engl. Access Control)
Die Zugriffskontrolle regelt, wer Unternehmensdaten einsehen oder ändern darf.
Durch die Zugriffskontrolle wird sichergestellt, dass vertrauliche Daten wie bei-
spielsweise Kunden- oder Finanzdaten nur für autorisierte Personen zugänglich
sind. Es gibt vier Hauptarten von Zugriffskontrollen. Diese lauten Discretionary Ac-
cess Control, Mandatory Access Control, Role-based Access Control und Attribute-
based Access Control. [Cit19] Vor allem die letzten beiden sind relevant für diese
Arbeit und werden im Folgenden vorgestellt.

2.3.1 Role Based Access Control
Role Based Access Control (RBAC) wurde 1992 von David Ferraiolo und Rick Kuhn
vorgestellt. In RBAC definieren sich die Rechte eines Nutzers anhand der Rolle in
dem Unternehmen. Rollen bleiben in einem Unternehmen über einen Zeitraum re-
lativ konstant und die Zuweisung von Rechten kann deutlich vereinfacht werden.
Dadurch können potenzielle Fehler vermieden werden, wo einem Nutzer zu viele
2 Grundlagen                                                                        9

Rechte zugewiesen wurden. Es gibt 4 Stufen von RBAC, in der die Komplexität
stufenweise zunimmt. [SFK00]
Das einfachste Modell ist das Flat RBAC Modell. In diesem Modell werden den
Nutzer eine Rolle zugewiesen. Dadurch werden dem Nutzer bestimmte Berech-
tigungen eingeräumt. Ein Nutzer kann mehrere Rollen gleichzeitig besitzen und
eine Rolle kann auch mehrere Berechtigungen mit sich bringen. Ein Nutzer kann
sich gleichzeitig in mehreren Rollen befinden. In diesem Modell muss eindeutig
nachvollziehbar sein, welche Rollen einem Nutzer zugewiesen wurden. Das Flat
RBAC Modell scheitert daran die hierarchische Struktur in einem Unternehmen
darzustellen. In einem Unternehmen überschneiden sich Berechtigungen für be-
stimmte Rollen. [SFK00]
Dies wird in der 2. Stufe, dem hierachical RBAC Modell behoben. In diesem können
Hierarchien von Rollen erstellt werden. Erbt ein Nutzer durch seine Rolle von einer
anderen Rolle, hat dieser die vollen Rechte der geerbten Rolle. Dieses Modell kann
weiter eingeschränkt werden zu dem Restricted Hierachical RBAC. In dem ist es er-
laubt nur einfache Vererbungsstrukturen wie einen Baum darzustellen. [SFK00]
Die nächste Stufe wird Constrained RBAC genannt. Wie der Name schon sagt wer-
den hier gegenüber von Hierachical RBAC Einschränkungen eingeführt. Es soll
dadurch Betrug und Fehler in der Rollenzuteilung verhindert werden. Um dies
umzusetzen wird die sogenannte Funktionstrennung (engl. Seperation Of Duty)
angewandt. Dafür werden Aufgaben auf verschiedene Rollen aufgeteilt um zu
verhindern, dass ein Nutzer zu viel Autorität besitzt. Unterstützt wird die Funk-
tionstrennung durch das Prinzip der Least Privileges. In diesem Prinzip geht es
darum, dem Nutzer nur so viele Privilegien zu geben, wie er unbedingt benötigt,
um seine Arbeit zu erledigen. Dadurch wird verhindert, dass ein Nutzer unnötige
und möglicherweise gefährliche Aktionen durchführen kann. Die Funktionstren-
nung kann von statischer Natur sein und es kann, wenn ein Nutzer eine bestimmte
Rolle besitzt, eine andere durch Funktionstrennung in Konflikt stehende Rolle nicht
zugewiesen werden. Die Funktionstrennung kann auch dynamisch erfolgen. Hier
können einem Nutzer zwar mehrere Rollen zugewiesen werden, aber in einer Ses-
sion kann er nur eine der beiden Rollen nutzen. Ein Beispiel hierfür ist ein Kassierer
und ein Vorgesetzter eines Kassierers. Dem Vorgesetzten ist es erlaubt Änderungen
an der Kasse des Kassierers zu bestätigen. Der Kassierer kann auch die Rolle des
Vorgesetzten einnehmen. Hierfür wird er durch RBAC aber verpflichtet erst die Kas-
se zu schließen und die Rolle des Kassierers für die Session aufzugeben. [SFK00]
Die letzte Stufe wird Symmetric RBAC genannt. Hier muss nachvollziehbar sein,
2 Grundlagen                                                                      10

welche Berechtigungen durch eine Rolle gewährt wird. Darüber hinaus muss auch
die Umkehrung erfüllt sein. Hat man eine bestimmte Berechtigung muss es mög-
lich sein alle Rollen aufzulisten, die diese Berechtigung erteilt. Das Überprüfen der
Berechtigungen eines Nutzers muss dann durchgeführt werden, wenn z. B. der
Nutzer seinen Job in dem Unternehmen wechselt. Es sollte immer versucht werden
das Prinzip der Least Privileges einzuhalten. In großen verteilten Systemen kann
Symmetric RBAC schwer zu implementieren sein und wird deshalb erst in der 4.
Stufe erwähnt. [SFK00]

2.3.2 Attribute Based Access Control
Attribute Based Access Control (ABAC) benutzt Attribute um eine Zugriffsent-
scheidung zu treffen. Weiterhin gibt es sogenannte Policies, die anhand der Attri-
bute entscheiden, ob das Subjekt berechtigt ist die Aktion am Objekt durchzufüh-
ren. [Okt20]
Attribute können vielseitig sein:

   • Sie können sich auf den Benutzer, Subjekt beziehen, wie z.B. Name, Abteilung
     sein.

   • Sie können sich auf Aktionen beziehen, wie z.B. GET, POST, PUT, DELETE.

   • Sie können Attribute von Ressourcen sein, wie z.B. Arbeitszeit eintragen.

   • Sie können sich auf den Kontext von einer Interaktion beziehen, z.B. Zeit,
     Gerät [Okt20]

Die Umsetzung in einem Unternehmen hängt von vielen Faktoren ab, wie der
Größe des Unternehmens, der Verteilung der Ressourcen und der Bedürfnisse der
Benutzer. Deshalb können die einzelnen Zugriffsmechanismen physisch und lo-
gisch separiert werden. [HFK+ 14]

Policy Decision Point (PDP):
PDP wertet die Policies, die den Zugriff auf das geschützte Objekte regeln anhand
der Attribute des Subjekts aus und gibt diese Entscheidung an den Policy Enforce-
ment Point weiter. Hat der PDP nicht alle Informationen um eine Entscheidung zu
treffen kann er beim Policy Information Point anfragen.
2 Grundlagen                                                                     11

Policy Enforcement Point (PEP):
PEP setzt die Policy Entscheidung vom PDP um. Das heißt der PEP entscheidet, ob
ein Subjekt das anfragt Zugriff auf das geschützte Objekt erhält.
Policy Information Point (PIP):
PIP dient als Quelle für den PDP, damit der PDP Attribute oder Information die
zur Auswertung der Policies benötigt werden erhalten kann.
Policy Administration Point (PAP):
PAP ist zuständig für das Verwalten und Testen von Policies. [HFK+ 14]

2.3.3 Vergleich RBAC und ABAC
In RBAC kann einfach nachvollzogen werden, welche Berechtigungen mit einer
Rolle verknüpft sind. Außerdem können die Rollen bestimmt werden, die einem
Nutzer zugewiesen wurden. Das macht es einfach zu überprüfen, welche Berech-
tigungen ein Nutzer im System hat. Das Problem bei RBAC ist, dass die Rollen
statisch sind und es keine dynamischen Attribute, wie die Zeit gibt. Dies lässt sich
mit ABAC lösen. Hier können einfach dynamisch Attribute, wie der Standort in die
Entscheidung, ob der Zugriff erlaubt werden soll mit einfließen. Bei ABAC müs-
sen aber eine hohe Anzahl an Attributen verwaltet und auch verstanden werden,
da je nachdem welche Attribute ein Nutzer hat der Zugriff erlaubt oder verboten
wird. Es kann also nicht einfach nachvollzogen werden welche Berechtigungen ein
Nutzer hat, wie es in RBAC möglich ist. [CW19]

2.3.4 Kombination von RBAC und ABAC
Beide Ansätze haben ihre Vorteile und Nachteile. Um die Nachteile auszugleichen
wurden Ansätze entwickelt, die beide Ansätze verbinden.
Es gibt den Attribute-centric Ansatz, in dem Rollennamen einfach als Attribute des
Nutzers betrachtet werden. Dieser Ansatz schöpft die Vorteile von ABAC voll aus,
aber es geht die Einfachheit der Verwaltung durch RBAC verloren, nämlich die
Beziehung zwischen Berechtigungen und Rollen.
Ein anderer Ansatz ist der Role-centric Ansatz. Hierbei werden Attribute genutzt,
um RBAC einzuschränken. Ein Attribut kann die Berechtigungen eines Nutzers
nur einschränken und diese nicht erweitern. Durch diesen Ansatz wird einiges an
der Flexibilität von ABAC eingebüßt, aber das System erhält die RBAC Möglich-
keiten und es kann die maximale Anzahl der Berechtigungen eines Nutzers einfach
2 Grundlagen                                                                       12

    nachvollzogen werden. [KCW10]
    Insgesamt bleibt festzuhalten, es gibt leider keine Einheitslösung, um die Zugriffs-
    kontrolle zu implementieren. Dies hängt von vielen Faktoren, wie der Struktur
    des Unternehmens und wie fein die Berechtigungen eines Nutzers sein sollen, ab.
    Es sollte der Ansatz gewählt werden, der am besten im Unternehmen umgesetzt
    werden kann.

    2.4 JSON Web Token
    JSON Web Token (JWT) repräsentieren eine Menge von Claims in einem JSON
    Objekt, die zwischen zwei Parteien ausgetauscht werden können. Ein Claim ist
    ein Name/Wert Paar. Der Name ist immer ein String. Der Wert kann ein beliebiger
    JSON Wert sein. Es kann sich also zum Beispiel um ein Array, String, JSON Objekt
    handeln. Die Claims sind der Payload einer JSON Web Signature (JWS) oder einer
    JSON Web Encryption (JWE). Der Unterschied zwischen diesen beiden ist, dass eine
    JWS nur die Datenintegrität sicherstellt und eine JWE zusätzlich zur Datenintegrität
    auch die Informationsvertraulichkeit. [JBS15]

    2.4.1 Aufbau
    Ein JWT ist in 3 Teile gegliedert Header, Payload und Signatur.
    In diesem Beispiel wird ein JWT mit einer JWS gezeigt, der Aufbau mit einer JWE
    ist sehr ähnlich. Ein Beispiel für einen Header wird in Listing 2.1 dargestellt.
1   {
2       "typ": "JWT",
3       "alg":" HS256 "
4   }

                          Listing 2.1: JWT Header (Quelle: [JBS15])

    Der Typ gibt an, dass es sich um einen JSON Web Token handelt.
    Alg ist der Algorithmus, der für die Signatur verwendet wurde. [JBS15]
2 Grundlagen                                                                     13

    Die Claims des Payloads sind anwendungsspezifisch.
    Der JWT Standard gibt aber trotzdem standardisierte Claims an. Die wichtigsten
    werden nun anhand des Beispiels in Listing 2.2 erläutert. [JBS15]
1   {
2       "iss": "http :// www.jwt.de/ issuer ",
3       "iat": 1589306239,
4       "exp": 1589307440,
5       "aud": "www.aud.com",
6       "sub": "j. steinleitner "
7   }

                  Listing 2.2: JWT Payload (Quelle: In Anlehnung an [JBS15])

    iss (Issuer) Claim:
    Der Issuer Claim gibt den Service an, der den Token ausgestellt hat. Es handelt sich
    hierbei meistens um eine URL. [JBS15]

    iat (Issued At) Claim:
    Der Issued At Claim gibt den Zeitpunkt an, an dem der JWT ausgestellt wur-
    de. [JBS15]

    exp (Expiration Time):
    Der Expiration Time Claim ist wiederum ein Zeitpunkt, der dieses Mal angibt, bis
    wann der JWT gültig ist. Ist dieser abgelaufen, muss er abgewiesen werden. [JBS15]

    aud (Audience) Claim:
    Die Audience gibt den Empfänger des Tokens an. Es kann sich auch um mehre-
    re handeln. Diese werden dann in einem JSON Array angegeben. Es handelt sich
    meistens um eine URL, welche den Service, für den der Token bestimmt ist, ein-
    deutig identifiziert. [JBS15]

    sub (Subject) Claim:
    Der Subject Claim identifiziert den Benutzer oder die Anwendung, für den der
    Token ausgestellt wurde. [JBS15]

    Am Ende jedes Tokens erhält dieser noch eine JWS, um sicherzustellen, dass der
    Token nicht verändert werden kann. Für die Signatur wird in diesem Beispiel der
    HMAC-SHA256 Algorithmus genutzt. Um die Signatur zu berechnen werden der
2 Grundlagen                                                                   14

Header und Payload jeweils einzeln Base64URL kodiert und weiterhin mit einem "
." dazwischen zusammengefügt. Die Base64URL Kodierung ist eine Modifikation
von Base64, die nur URL konforme Zeichen enthält. [JBS15]

           HMAC_SHA256(base64 URL(Header) + "." + base64 URL(Body), secret)

In diesem Beispiel wird als Secret 123456 genutzt.
Die Base64URL kodierte Signatur für den obigen Header und Payload lautet fol-
gendermaßen:

 KzDbcXjxH_FhQnBe0Aliloqrt0KRovysDY43jt-gmcc

Der Token wird nun aus den 3 einzelnen Teilen folgendermaßen zusammengebaut:

base64 URL(Header) + "." + base64 URL(Body) + "." + base64 URL(Signatur)

Aus dem obigen Beispiel folgt nun der komplette JSON Web Token. Die Zeilenum-
brüche werden nur zur Veranschaulichung eingefügt. Dadurch kann man eindeutig
die 3 Bestandteile des JSON Web Token erkennen. [JBS15]

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
.eyJpc3MiOiJodHRwOi8vd3d3Lmp3dC5kZS9pc3N1ZXIiLCJpYXQiOjE1ODkzMDYyMzks
ImV4cCI6MTU4OTMwNzQ0MCwiYXVkIjoid3d3LmV4YW1wbGUuY29tIiwic3ViIjoiai5zd
GVpbmxlaXRuZXIifQ
.KzDbcXjxH_FhQnBe0Aliloqrt0KRovysDY43jt-gmcc

2.5 OAuth 2.0
OAuth 2.0 erlaubt einem Drittanbieter limitierten Zugriff auf einen HTTP-Service.
Ein Beispiel hierfür ist eine eigene Kalender-App, die zugriff auf den Google Ka-
lender haben möchte, um den Terminkalender zu lesen. Eine Möglichkeit wäre der
Anwendung den Benutzernamen und das Passwort zu überlassen und darauf zu
vertrauen, dass diese nur den Kalender abruft und nicht auch noch die E-Mails
oder das Konto Passwort ändert. Für diesen Anwendungsfall wurde das Protokoll
OAuth spezifiziert. Heutzutage ist OAuth ein wichtiger Standard im Internet.
2 Grundlagen                                                                         15

2.5.1 Grundbegriffe
Um die OAuth Flows zu beschreiben werden zunächst die Grundbegriffe erklärt.
In OAuth 2.0 werden 4 Rollen definiert.
Es gibt den Resource Owner, der den Zugriff auf die geschützte Ressource erlaubt.
Die zweite Rolle ist der Resource Server. Dieser hostet die geschützte Resource und
kann bei Anfragen auf eine geschützte Ressource antworten.
Weiterhin gibt es noch den Client, bei dem es sich um eine Anwendung handelt, die
im Auftrag des Resource Owners auf eine geschützte Resource zugreifen möchte.
Ein Client kann zum Beispiel ein Webbrowser sein.
Als letztes gibt es noch den Authorization Server, der den Resource Owner authen-
tifiziert und wenn dies Erfolgreich war ein Access Token ausstellt. [Har12]

Die oben genannte Client Rolle kann in zwei Arten von Clients unterteilt werden,
je nachdem, ob sie sich sicher beim Authorization Server authentifizieren kann. Das
bedeutet, ob sie die Vertraulichkeit ihrer Credentials (z. B. Passwort, Zertifikat, ...)
sicherstellen können. Ist das möglich werden sie confidential genannt. Es kann sich
hierbei z. B. um einen sicheren Server handeln. Kann ein Client seine Credentials
nicht geheim halten, handelt es sich um ein public Client. Beispiele für public Clients
sind eine App oder eine Browseranwendung.
Die Unterscheidung ist wichtig, da je nachdem ob es sich um ein public oder con-
fidential Client handelt ein anderer OAuth Flow genutzt werden sollte. [Har12]

Als letztes werden noch die 2 verschiedenen Arten von Token betrachtet.
Es gibt Access Token, mithilfe dessen auf eine geschützte Ressource zugegriffen wer-
den kann. In Access Tokens kann ein Scope festgelegt werden, der angibt auf welche
geschützten Daten das Client zugriff erhält. Es erhält weiterhin einen Zeitstempel,
der die Gültigkeit angibt. Das Access Token soll für das Client opaque sein.
Refresh Token werden benutzt, um ein neues Access Token zu erhalten. Mithilfe des
Refresh Token kann ein neues Access Token angefordert werden, wenn das alte
abgelaufen oder ungültig geworden ist. Es kann theoretisch auch der Scope in dem
Refresh Token für das neue Access Token eingeschränkt werden. Refresh Token
sind deutlich länger gültig, als Access Token. Deren Gültigkeit beträgt zumeist nur
mehrere Minuten. Die Dauer der Gültigkeit muss gegenüber der Sicherheit der
Anwendung abgewogen werden. [Har12]
2 Grundlagen                                                                     16

2.5.2 Flows
OAuth unterscheidet verschiedene Flows, die je nach Anwendung genutzt werden
sollen. Bei dem Resource Owner Password Credentials Flow wird der Nutzerna-
me und das Passwort an den Authorization Server geschickt. Dies soll aber genau
durch OAuth verhindert werden. Der Flow ist nur für die Abwärtskompatibilität
vorhanden und wird hier nicht erläutert. [Har12] Ein weiterer Flow, der heutzu-
tage nicht mehr genutzt werden sollte, ist der Implicit Flow. Der Implicit Flow
war für Single Page Web Application gedacht. Dieser Flow ist anfällig dafür das
Access Token zu leaken und auch für Replay-Attacken. In diesem Flow wird das
Access Token in der URL zurückgesendet. Dadurch kann es passieren, dass der
Browser es in der Historie speichert. Hat ein Angreifer zugriff auf diese kann er es
auslesen. Aufgrund dieser Sicherheitsrisiken wird der Implicit Flow nicht weiter
erläutert. [LBLF20] Es bleiben noch der Authorization Code Flow und der Client
Credentials Flow übrig, auf die im Folgenden weiter eingegangen wird. Es gibt auch
noch vorgeschlagene Standards die schon Einzug in OAuth Implementierungen er-
halten haben und auch genutzt werden sollten. Bei den vorgeschlagenen Standards
werden der Authorization Code Flow with PXCE und der Token Exchange Flow
vorgestellt. Es werden Sequenzdiagramme für die einzelnen Flows aufgezeigt. In
diesen sind nur die in OAuth definierten Anfragen und Antworten aufgezeigt. Es
werden dazwischen weitere Daten ausgetauscht, die aber außerhalb des Bereichs
von OAuth liegen.
2 Grundlagen                                                                     17

2.5.2.1 Authorization Code Flow

Der Authorization Code Flow, wie in Abb. 2.1 ist für confidential Clients gedacht.

  Abb. 2.1: OAuth Authorization Code Flow (Quelle: In Anlehnung an [Har12])

1. Der Flow wird vom Client gestartet, indem er den User-Agent (z. B. Webbrowser)
auf den Authorization Server umleitet. Der Client schickt in diesem Schritt Para-
meter, wie seine Client-ID und die Umleitungs-URI mit, auf die der Nutzer später
wieder auf den Client umgeleitet wird.
2. Der Authorization Server authentifiziert den Resource Owner und wartet nun,
ob der Resource Owner den Zugriff erlaubt oder verbietet.
3. Wird der Zugriff erlaubt, wird der User-Agent vom Authorization Server auf den
Client zurück umgeleitet. Die URI, auf die er umgeleitet wird, wurde im Schritt 1
angegeben. Diese URI enthält den Authorization Code.
4. Der Client fordert nun beim Authorization Server mithilfe des Authorization
Code ein Access Token an. Der Client authentifiziert sich bei der Anfrage beim
Authorization Server.
5. Im letzten Schritt authentifiziert der Authorization Server den Client, überprüft
2 Grundlagen                                                                     18

den Authorization Code. Ist alles korrekt, gibt der Server ein Access Token zurück
und optional ein Refresh Token, das genutzt werden kann, um das kurzlebigere
Access Token zu erneuern. [Har12]

Es wird im Schritt 3 nicht direkt ein Access Token ausgestellt, sondern nur ein
Authorization Code, da der Access Token sonst direkt an den Nutzer ginge. In
diesem Fall geht es nur an den Client, bei dem es sich normalerweise um einen
Backend-Server handelt. Das heißt, wenn ein Angreifer einen Authorization Code
abgreift kann er immer noch nicht auf die geschützte Ressource zugreifen, da sich
der Client in Schritt 4 beim Authorization Server zusätzlich authentifiziert, um ein
Access Token zu bekommen. [Har12]

2.5.2.2 Authorization Code Flow with PKCE

OAuth public Clients sind dort für Attacken anfällig, wo der Authorization Code
abgefangen werden kann. Dies kann auf Transportwegen geschehen, die nicht mit
TLS verschlüsselt sind, wie inter-applikation Kommunikation mit dem Betriebs-
system des Clients. Hat der Angreifer Zugriff auf den Authorization Code, kann er
diesen für ein Access Token umtauschen. Bei diesem Flow geht es um die Verhin-
derung eines komplexen Angriffs, der in der Praxis vorgekommen ist. Bei diesem
Angriff läuft eine bösartige Anwendung auf dem Client. Die bösartige Software
registriert ein benutzerdefiniertes URI Schema auf die URI, die genutzt wird, um
den Authorization Code an das Client zu senden. Das Betriebssystem muss es in
diesem Fall erlauben, dass benutzerdefinierte URIs von mehreren Anwendungen
gleichzeitig genutzt werden. Der Authorization Code wird in diesem Fall an die
bösartige Applikation und an das valide OAuth Client gesendet und kann, da es
sich um ein public Client handelt und dadurch keine Credentials geheim gehalten
werden können, einfach gegen ein Access Token umgetauscht werden. [SBA15]
2 Grundlagen                                                                     19

Es werden in Abb. 2.2 die Unterschiede zu dem Standard Authorization Code Flow
aufgezeigt.

Abb. 2.2: OAuth Authorization Code Flow with PKCE (Quelle: In Anlehnung an
         [Har12, SBA15])

1. Der Client leitet wie bei dem normale Authorization Code Flow den User-Agent
mit den üblichen Parametern auf den Authorization Server um. Zusätzlich gene-
riert der Client sich einen zufälligen String mit hoher Entropie. Dieser String wird
Code-Verifier genannt. Aus diesem leitet er durch die Funktion t eine transformierte
Version ab. Bei der Funktion t kann es sich um die Hash Funktion SHA-256 han-
deln. Die transformierte Version wird Code-Challenge genannt. Er schickt diesen
Parameter BASE64URL kodiert und mit dem Namen der Funktion, die genutzt
wurde zusätzlich an den Authorization Server.
2. Der Authorization Server antwortet wie üblich, aber speichert die transformierte
Code-Challenge und den Namer der Funktion, die für die Transformation genutzt
2 Grundlagen                                                                     20

wurde, ab.
3. Der Client sendet den Authorization Code an den Authorization Server, um ein
Access Token zu erhalten. Zusätzlich sendet er den Code-Verifier mit.
4. Der Authorization Server transformiert den Code-Verifier und vergleicht es mit
dem aus Schritt 2. Sind diese gleich, wird ein Access Token zurückgegeben. Wenn
nicht wird der Zugriff verweigert. [SBA15]

Fängt ein Angreifer den Authorization Code ab und möchte es für ein Access Token
umtauschen ist das nicht möglich, da er den Code-Verifier nicht kennt. [SBA15]

2.5.2.3 Client Credentials Flow

Möchte ein Client eine geschützte Ressource aufrufen kann es nur mit seinem Client
Credentials am Authorization Server ein Access Token erhalten. [Har12]

   Abb. 2.3: OAuth Client Credentials Flow (Quelle: In Anlehnung an [Har12])

1. Der Client authentifiziert sich bei dem Authorization Server und fordert ein Ac-
cess Token an.
2. Der Authorization Server authentifiziert den Client. Ist die Anfrage valide, wird
ein Access Token zurückgegeben. [Har12]

Dieser Flow kann bei Microservices von Nutzen sein, um einen Microservice im
2 Grundlagen                                                                     21

Backend aufrufen zu können. Das Problem hierbei ist, dass der Nutzerkontext in
dem Access Token verloren geht. Das heißt der Microservice hat volle Berechtigun-
gen auf den Backend-Service, obwohl der Nutzer eine Aktion nicht durchführen
darf. Dies verstoßt gegen das Least Privileg Prinzip.

2.5.2.4 Token Exchange Flow

Der Token Exchange ist eine Verbesserung des Client Credentials Flows.

       Abb. 2.4: OAuth Token Exchange (Quelle: In Anlehnung an [Har12])

1. Der Client authentifiziert sich beim Authorization Server und schickt das Ac-
cess Token des Nutzers an den Token Endpunkt des Authorization Server. Bei der
Anfrage kann auch die Audience, die für das neue Token gelten soll, angegeben
werden.
2. Ist die Authentifizierung erfolgreich, wird ein Access Token zurückgegeben.
Das neue Access Token erhält die Nutzerinformation. Somit kann das Backend
selbst eine Autorisierung durchführen. [JNC+ 20]
2 Grundlagen                                                                     22

  Die Spezifikation des Token Exchange Flow geht aber noch deutlich darüber
hinaus. Es können, wenn vom Authorization Server akzeptiert, auch Saml Token
oder die in OpenID Connect spezifizierten ID Token umgetauscht werden. [JNC+ 20]

2.6 OpenID Connect
Bei OpenID Connect handelt es sich um ein Authentifizierungsprotokoll, das auf
OAuth aufbaut. Es hilft den Endbenutzer durch den Authorization Server zu au-
thentifizieren und hilft darüber hinaus Clients Informationen über den Nutzer zu
erhalten. Es gibt das sogenannte ID Token, das die Informationen über den Nutzer
als Claims in ein JWT gepackt zurückgibt. Es müssen die Claims, die in Kapitel 2.3.1
aufgezeigt wurden, vorhanden sein. Darüber hinaus gibt es noch weitere. Zusätz-
lich zu dem ID Token gibt es noch den UserInfo Endpunkt, der mit einem Access
Token aufgerufen werden kann und auch Claims über den Nutzer im JSON Format
zurückgibt. OpenID Connect hat wie OAuth verschiedene Flows. Es gibt den Im-
plicit, Authorization Code und Hybrid Flow. Bei dem Implicit und Authorization
Code Flow gibt es kaum Unterschiede zu denen in OAuth. Der Hybrid Flow ist
eine Mischung aus dem Authorization Code Flow und Implicit Flow. [SBJ+ 14] Es
wird in dieser Arbeit nur der Authorization Code Flow weiter betrachtet.
2 Grundlagen                                                                  23

2.6.1 Authorization Code Flow
Der Authorization Code Flow ist fast identisch zu dem in OAuth. Es werden die
Unterschiede in Abb. 2.5 aufgezeigt.

Abb. 2.5: OpenID Connect Authorization Code Flow (Quelle: In Anlehnung an
            [Har12])

1. Der User-Agent wird wie in OAuth vom Client umgeleitet. Die Anfrage erhält
im Scope aber zusätzlich den Parameter openid. Der Scope Parameter wird auch
an den Authorization Server weitergeleitet. Nur durch diesen Parameter weiß er,
dass es sich um eine OpenID Connect anfrage handelt.
Die Schritt 2 bis 4 sind identisch zu denen im OAuth Flow.
5. Zusätzlich zu dem Access Token und dem optionalen Refresh Token wird auch
ein ID Token zurückgegeben.
6. Dieser Schritt ist neu. Der Client validiert in diesem das erhaltene ID Token.
[SBJ+ 14]
2 Grundlagen                                                                    24

Bei OpenID Connect kann natürlich auch der Authorization Code Flow with PXCE
genutzt werden. Hierbei ändert sich nichts weiteres in OpenID Connect zu den
oben genannten Änderungen.

2.7 Microservices
Es gibt keine eindeutige Definition von Microservices. Häufig werden zwei Defini-
tionen herangezogen. Die erste ist von Sam Newman.

„Microservices are small, autonomous services that work together.“ [New15]

Die zweite Defintion von Micrservices kommt von Martin Fowler:

„Microservice architectural style is an approach to developing a single application
as a suite of small services, each running in its own process and communicating
with lightweight mechanisms, often an HTTP resource API. These services are built
around business capabilities and independently deployable by fully automated de-
ployment machinery. There is a bare minimum of centralized management of these
services, which may be written in different programming languages and use diffe-
rent data storage technologies.“ [Fow14]

Beide Definitionen besagen, dass es sich um kleine Services handelt, die mitein-
ander kommunizieren und selbständig sind. Die Definition von Fowler geht noch
genauer darauf ein, wie die Kommunikation zwischen den Services oft geschieht.
Nämlich über HTTP API Schnittstellen.

2.7.1 Vorteile gegenüber eines Monolithen
Microservices haben im Gegensatz zu einem Monolithen viele Vorteile. Durch die
Zerlegung des Monolithen in kleine Services können die einzelnen Microservices
skaliert und dadurch einfacher auf Nachfragesteigerungen reagiert werden. Ein
weiterer Vorteil ist die technologische Flexibilität. Jedes Entwicklerteam kann die
Technologien für den Microservice nutzen, die am besten zum Lösen des Problems
passen.
Durch die verteilte Architektur erhöht sich die Ausfallsicherheit der Anwendung.
2 Grundlagen                                                                     25

Der Ausfall einer Komponente führt nicht zum Ausfall der ganzen Anwendung.
Es wird hier lediglich eine Funktionalität beeinträchtigt. [AWS20]

2.7.2 Sidecar-Muster
Zur Isolation und Kapselung werden Komponenten einer Software in einen eigenen
Container ausgelagert. Dadurch kann eine technologische Unabhängigkeit von der
Hauptanwendung erreicht werden. Dieses Muster wird Sidecar genannt. Es bietet
unterstützende Funktionen für die Hauptanwendung .
Anwendungen benötigen Funktionen wie Monitoring, Logging und Autorisierung.
Diese Funktionen können alle als ein Sidecar implementiert werden und dadurch
in allen Services genutzt werden. Das hat einige Vorteile. [olp19]

   • Das Sidecar kann in einer anderen Programmiersprache geschrieben werden,
     als die Primäranwendung.

   • Es gibt kaum eine Latenz bei der Kommunikation zwischen dem Sidecar und
     der Primäranwendung [olp19]

Dieses Muster wird oft in containerisiserten Anwendungen und damit auch oft in
Microservices genutzt. [olp19]

2.8 CAP-Theorem
Das CAP-Theorem von Professor Eric A. Brewer besagt, dass in verteilten Systemen
immer nur zwei der drei verlangten Charakteristiken (Konsistenz, Verfügbarkeit,
Partitionstoleranz) erreicht werden können. [Edu19]

Konsistenz:
Konsistenz meint, dass alle Clients die gleichen Daten zur selben Zeit sehen. Es ist
also nicht relevant zu welchen Knoten die Clients verbunden sind, sie sehen alle die
gleichen Daten. Werden Daten an einen Knoten geschrieben, müssen diese sofort
an die anderen Knoten weitergeleitet werden, bevor das Schreiben auf den initialen
Knoten beendet wurde. [Edu19]
2 Grundlagen                                                                      26

Verfügbarkeit:
Ein Client soll auch eine Antwort bekommen, wenn ein oder mehrere Knoten nicht
mehr funktionieren. Die funktionierenden Knoten in einem verteilten System ge-
ben eine korrekte Antwort zurück. [Edu19]

Partitionstoleranz:
Eine Partition ist eine Unterbrechung der Verbindung in einem verteilten System. Es
kann sich um eine unterbrochene oder eine verspätete Verbindung zwischen zwei
Knoten handeln. Partitionstoleranz bedeutet, dass auch wenn die Kommunikation
zwischen zwei oder mehreren Knoten unterbrochen ist, das gesamte verteilte Sys-
tem immer noch funktioniert. [Edu19]

Ein falscher Schluss, der oft aus dem CAP-Theorem gezogen wird ist, dass im-
mer nur exakt 2 der 3 Eigenschaften erfüllt werden können. Die drei Eigenschaften
müssen als kontinuierlich und nicht als binäre Größen betrachtet werden. [Bre12]
Folglich müssen in einer Eigenschaft Abstriche gemacht werden, um mehr von den
anderen beiden zu erreichen. Zielt man zum Beispiel ein System, dass eine hohe
Verfügbarkeit und Partitionstoleranz hat, heißt das nicht, dass das System kom-
plett inkonsistent ist. Es gibt in der Konsistenz z. B. die Abstufung der eventuellen
Konsistenz. Es wird hier sichergestellt, dass wenn keine Daten geupdatet werden,
nach einer bestimmten Zeit der neueste Wert zurückgegeben wird. [Vog09]
3 Fachliche Anforderungen                                                        27

3 Fachliche Anforderungen
In diesem Kapitel geht es um die fachlichen Anforderungen für die Authentifizie-
rung und Autorisierung.

3.1 Authentifizierung

3.1.1 Unterstützung von OpenID Connect
Die Authentifizierung soll mit OpenID Connect vorgenommen werden, da es sich
hier um einen Standard handelt, der sehr häufig für die Authentifizierung im
Internet genutzt wird und sich auch bewährt hat. Weiterhin arbeitet dieser Standard
mit JWTs, was für zustandslose Microservices vom Vorteil ist.

3.2 Autorisierung

3.2.1 Lesbarkeit der Policies
Die Policies sollten so geschrieben werden, dass sie einfach lesbar und dadurch auch
besser nachvollziehbar sind. Denn sonst kommt es leicht zu Fehlern, bei denen ein
Nutzer Berechtigungen hat, die er nicht haben sollte.

3.2.2 Austauschbarkeit der Policies
Die Policies sollten verändert werden können und ohne neues deployen des Ser-
vices auch automatisch greifen. Es kann sein, dass sich Policies in einem Unterneh-
men oft ändern. Brauchen Nutzer zum Beispiel für ein neues Projekt Zugriff auf
geschützte Daten sollte es möglich sein, einfach die Policies zu ändern, damit die
Nutzer Zugriff haben, ohne den Service neu zu deployen.
3 Fachliche Anforderungen                                                         28

3.2.3 Testbarkeit der Policies
Die Policies sollten einfach getestet werden können. Dies hilft den Entwickler Fehler
zu erkennen. Zusätzlich werden Policies mit der Zeit geändert. Bei der ersten
Entwicklung werden Fälle in Betracht gezogen, an die beim Update der Policies
nicht mehr gedacht wird. Tritt dieser Fall ein, schlägt der Test fehl.

3.2.4 Plattformunabhängigkeit
Die Autorisierung sollte unabhängig von der im Service verwendeten Program-
miersprache funktionieren. Jeder Service soll in der Programmiersprache und mit
dem Framework programmiert werden, welche am besten zu dem Anwendungsfall
passt. Die Policies sollten aber immer in der gleichen Sprache geschrieben werden,
da diese zentral verwaltet werden sollen.

3.2.5 Performance
Damit das ganze System reaktionsfähig bleibt, sollte die Entscheidung über die Zu-
griffserlaubnis sehr schnell getroffen werden. Dies ist deshalb so wichtig, da jeder
Microservice selbst eine Autorisierung durchführen muss. Dadurch, dass ein Micro-
service weitere Microservices aufrufen kann, summiert sich die Auswertungszeit
der Policies. Deshalb sollte die Dauer möglichst minimal gehalten werden. Manch-
mal kann die Authentifizierung nicht durch JWTs oder lokale Daten geschehen und
es müssen andere Microservices oder Datenbanken aufgerufen werden, das einen
negativen Einfluss auf die Auswertungszeit hat.

3.2.6 Verteilte Autorisierung
Jeder Service muss aufgrund der Sicherheit selbst eine Autorisierung durchführen.
Es kann aber auch einen eigenen Service geben, der als Policy Decision Point fun-
giert und nur die Policy Enforcement lokal im Service durchgeführt wird. In dieser
Arbeit soll jeder Service selbst die Autorisierung durchführen. Der PDP und der
PEP laufen lokal im Service. Aus Sicht des CAP Theorems wirkt sich die durch
die verteilte Autorisierung hohe Verfügbarkeit auf die Konsistenz aus. Denn die
Policies sind alle lokal in den Services. Gibt es neue Policies kann es sein, dass
ein Service diese früher lädt als ein anderer und es zu kurzzeitigen inkonsistenten
Ergebnissen bei der Autorisierung kommen kann.
4 Technisches Konzept                                                           29

4 Technisches Konzept
Das technische Konzept handelt von den Technologien, die für die verteilte Au-
torisierung und die Authentifizierung genutzt werden und der Architektur der
Microservices, um die verteilte Autorisierung und die Authentifizierung umzuset-
zen.

4.1 Verwendete Technologien

4.1.1 Open Policy Agent
OPA ist eine Policy Engine die es erlaubt Policies im deklarativen Stil als Code zu
spezifizieren und damit Policy Entscheidungen von der Anwendung zu trennen.
OPA wird in vielen Anwendungsbereichen verwendet, beispielsweise in Microser-
vices, Kubernetes, CI/CD Pipelines oder API Gateways. [OPA20b] OPA wird immer
mehr im Cloud-Native-Umfeld genutzt. Denn durch die deklarative Sprache kön-
nen die Policies leserlich und verständlich geschrieben werden. Deshalb wird OPA
auch für diese Arbeit verwendet.
OPA arbeitet als Policy Decision Point. Benötigt eine Software eine Entscheidung,
fragt es bei OPA an und übergibt Daten, die für die Autorisierung relevant sind.
Dies kann z. B. ein Access Token und der Name der aufgerufene API sein. Zusätz-
lich hat OPA selbst noch einen Data-Store, wo zusätzlich Daten gespeichert werden
können, die relevant für die Auswertung sind. In OPA werden zwei Arten von
Daten unterschieden. Die einen werden über die Rest-API oder über den Bundle-
Service, der weiter unten erklärt wird, in OPA geladen. Diese Daten werden als base
documents bezeichnet. Auch die Regeln in den Policies können neue Dokumente
erzeugen. Diese werden dann als virtual documents bezeichnet, da diese durch die
Policies erzeugt wurden. [OPA20f]
4 Technisches Konzept                                                          30

    4.1.1.1 Rego

    Rego ist die Sprache die in OPA genutzt wird um zu Entscheiden, ob der Zugriff auf
    eine geschützte Ressource erlaubt oder verboten werden soll. Rego Queries sind
    im genaueren Sinn Behauptungen, die auf Basis von Policies und Daten, welche in
    OPA gespeichert sind auf die Wahrheit überprüft werden.
    Regeln in OPA können beliebige Werte zurückgeben. Eine Regel wird als wahr
    angenommen, wenn Sie einen Wert hat oder nicht explizit falsch ist. [OPA20g] Eine
    solche Regel wird in Listing 4.1 vorgestellt.
1   allow {
2       method := input . method
3       method == "GET"
4       input .path == [" contracts "]
5       isInsuranceAgent
6   }

                            Listing 4.1: Einfache Regel in Rego

    Mit „input“ werden die Daten angesprochen, die mit der Anfrage an OPA mitge-
    schickt werden. In der zweiten Zeile erfolgt eine Zuweisung von „input.method“
    an die lokale Variable „method“ durch den Zuweisungsoperator „:=“. Die lokale
    Variable muss äquivalent zu dem String „GET“ sein. Der Pfad muss äquivalent
    zu dem angegebenen Array sein. Im letzten Schritt wird eine andere Regel mit
    dem Namen „isInsuranceAgent“ referenziert, die auch in diesem Paket definiert
    ist. Gibt diese einen Wert zurück, der wahr ist und die obigen beiden Ausdrücke
    auch, wird die ganze Regel „allow“, wahr. Die einzelnen Ausdrücke werden alle
    und-verknüpft, d. h. ist ein Ausdruck in der Regel falsch, wird die ganze Regel
    falsch. Möchte man stattdessen eine oder-Verknüpfung erreichen schreibt man eine
    neue Regel mit dem gleichen Namen. Es muss dann nur eine der beiden Regeln
    wahr sein.
    Da es sich bei Rego um eine deklarative Sprache handelt, gibt es keine Schleifen.
    Um über Mengen oder Arrays zu iterieren wird einfach eine Variable, der noch kein
    Wert zugewiesen wurde, genutzt. Für diesen Fall gibt es auch das „_ “ Zeichen.
    Dieses Zeichen wird intern durch eine Variable ersetzt. [OPA20g]
4 Technisches Konzept                                                            31

1   array := [" hallo ", "welt"]
2

3   allow {
4       array [_] == " hallo "
5   }

              Listing 4.2: Iteration in Rego (Quelle: In Anlehnung an [OPA20g])

    Die in Listing 4.2 festgelegte „allow“ Regel kann in einer imperativen Program-
    miersprache folgendermaßen aussehen:
1   for ( String e: array ) {
2       if(e == " hallo ") return true;
3   }

    Listing 4.3: Iteration des Rego Beispiels in imperativer Sprache (Quelle: In
                 Anlehnung an [OPA20g]

    Hier ist darauf zu achten, dass der Ausdruck nicht für alle Werte korrekt sein muss,
    falls über Elemente iteriert wird und diese mit einem konstanten Wert verglichen
    werden. Der Ausdruck muss nur ein einziges Mal wahr sein
    Möchte man aus Regeln nicht nur einen Wert, sondern eine Menge zurückgeben
    muss der Name der Regel nur mit einer Variable in viereckigen Klammern beendet
    und dieser Variable dann Werte zugewiesen werden. [OPA20g]
1   array := [" hallo ", "welt"]
2

3   set[s] {
4       s := array [_]
5   }
6

7   allow {
8       set[" hallo "]
9   }

                             Listing 4.4: Erzeugen einer Menge

    In dem Beispiel Listing 4.4 wurde das Array in eine Menge umgewandelt. Es kann in
    einer Menge nur über alle Elemente iteriert oder überprüft werden, ob ein Element
    in der Menge existiert, wie in der „allow“ Regel geschehen.
    Möchte man hingegen ein Objekt erzeugen, funktioniert das sehr ähnlich.
4 Technisches Konzept                                                             32

1   array := [" hallo ", "welt"]
2

3   toUpperCaseArray := str {
4       c := concat (" ",array )
5       str := upper (c)
6   }

                            Listing 4.5: Erzeugen eines Objekts

    In Listing 4.5 wird mithilfe der Regel „toUpperCaseArray“ das Array in einen
    String umgewandelt, der dann nur Großbuchstaben enthält. Das Ergebnis muss
    der im Kopf spezifizierten Variable „str“, wie in Zeile 5 geschehen, zugewiesen
    werden. Dieses Objekt ist sehr einfach, es können deutlich kompliziertere Objekte
    erstellt werden, die auch einen Schlüssel und nicht nur einen Wert haben.
    Ein weiteres interessantes Feature ist Unifikation. Mit Unifikation kann gefragt
    werden, ob es Werte für Variablen gibt, um den Ausdruck wahr zu machen.
1   [x ,"welt"] = [" hallo ", y]

                    Listing 4.6: Unifikation in Rego (Quelle: [OPA20g]

    In dem Listing 4.6 wird in Rego gefragt, ob es eine Lösung gibt, dass diese Gleichung
    wahr wird. Die Lösung für diese Unifikation ist einfach.
    Die Variable x wird den Wert „hallo“ erhalten und die Variable y den Wert „welt“.
    Um die Policies in OPA zu testen, gibt es das „with“ Schlüsselwort. Mit diesem
    können Mocks erstellt werden. Es können Regeln, die Input Daten und auch lokale
    Daten gemockt werden.
    OPA hat darüber hinaus noch selbst eingebaute Funktionen. Es gibt zum Beispiel
    Funktionen, um Strings zu bearbeiten, JWTs zu validieren und auch ein HTTP-
    Client um HTTP-Aufrufe zu machen. [OPA20g]

    4.1.1.2 Filtern von Daten

    Ein Problem, das oft auftritt ist, dass man zu wenig Daten hat, um eine Entschei-
    dung zu treffen, ob der Zugriff erlaubt werden soll oder nicht. Ein Beispiel wäre,
    dass ein Kunde einen Vertrag abrufen möchte. Der Kunde ruft dafür den Service
    mit der eindeutigen ID des Vertrages auf. Diese ID sagt aber nichts darüber aus,
    zu welchem Kunden der Vertrag gehört. Eine Möglichkeit ist es, das Vertrags-
    Kunden-Mapping lokal in OPA zu halten. Das bringt aber deutliche Probleme mit
    sich, da OPA die Daten im Arbeitsspeicher hält und bei einer großen Firma die
4 Technisches Konzept                                                             33

    Datenmenge schnell sehr groß wird. Außerdem müssen die Daten bei jedem neuen
    Vertrag, der hinzukommt, geupdatet werden. Ein anderer Ansatz ist es mithilfe
    des HTTP-Clients anzufragen, ob dieser Vertrag zu den Kunden gehört. Dies kann
    Funktionieren, wenn eine HTTP Schnittstelle für die Datenbank bereitgestellt wird.
    Hier zahlt man aber wieder mit einem deutlichen Performanceverlust. Das gleiche
    Problem tritt auf, wenn der Nutzer eine Liste von Verträgen haben möchte. Er darf
    aber nicht alle sehen, sondern nur seine eigenen. OPA bietet für dieses Problem
    den Compile-Endpunkt an, um Regeln nur Teilweise auszuwerten, so weit wie es
    möglich ist. Bei der Auswertung gibt OPA einen abstrakten Syntaxbaum zurück,
    der in einen SQL-Ausdruck umgewandelt werden kann. Dies kann nicht nur für
    SQL-Datenbanken genutzt werden, sondern auch für NoSQL-Datenbanken wie
    MongoDB, es muss aber hier der abstrakte Syntaxbaum anders übersetzt werden.
    Die teilweise Auswertung von Policies wird anhand eines Beispiels erläutert.

                          filter {
         Policy               data. contracts [_]. customerID == input . userID
                          }
                          {
         Input                userID : "123456"
                          }
         Unbekannten [data.contracts]
         Output           data.contracts[_].customerID = 123456

        Tab. 4.1: Beispiel für die Datenfilterung (Quelle: In Anlehnung an [San18])

    OPA hat, wie in Tabelle 4.1 gezeigt, die folgende Policy gegeben. Als Input wird die
    ID des Nutzers übergeben. Die Unbekannten sind alle Verträge, da diese nicht lokal
    in OPA gespeichert werden. Die Unbekannten müssen beim Aufruf des Compile-
    Endpunkts mitgeschickt werden. Der Ausdruck „data.contracts“ kann in diesem
    Fall als eine Tabelle mit dem Namen „contracts“ in einer Datenbank gesehen wer-
    den. In dieser Tabelle gibt es ein Attribut mit dem Namen „customerID“. Dieses
    Attribut muss in diesem Fall also gleich „123456“ sein. Der SQL-Ausdruck könnte
    also folgendermaßen aussehen.
1   SELECT * FROM contracts WHERE customerId = ’123456 ’

    Listing 4.7: Beispiel für einen durch die Datenfilterung erzeugten SQL-Ausdruck
Sie können auch lesen