Logo von Developer

Suche
preisvergleich_weiss

Recherche in 2.337.641 Produkten

Bernd Schönbach 3

Nutzer-Authentifizierung in Microservice-Umgebungen

Nutzer-Authentifizierung in Microservice-Umgebungen

Das Einloggen auf einer Webseite sollte sich einfach gestalten, wenn eine monolithische Architektur im Hintergrund ihren Dienst verrichtet. Was aber, wenn die Webseite von vielen Microservices befeuert wird? Woher wissen diese, dass die Nutzer die sind, die sie vorgeben zu sein? Hierfür können JSON Web Tokens eine sichere und performante Lösung sein.

Laut einer Bitkom-Studie verwenden 37 Prozent der Internetnutzer elf bis zwanzig Online-Dienste mit Login-Funktion. Für den Nutzer scheint der Vorgang des Einloggens im Frontend immer gleich zu sein. Benutzername oder E-Mail, Passwort, Enter – fertig. Im Backend sieht die Angelegenheit etwas anders aus. Bei einer monolithischen Backend-Umgebung ist das Autorisierungssystem impliziert, und die Verifizierung des Users ist kein Problem. Hier kann die Anwendung das Tracking des Nutzers übernehmen.

Laut einer Studie des Softwareherstellers LeanIX geht der Trend in Unternehmen zur Nutzung von Microservices, und in solchen Umgebungen gestaltet sich die Autorisierung schwieriger. Hier müssen sich die Microservices entweder darauf verlassen, dass der Nutzer autorisiert ist, oder sie fragen bei jedem Aufruf den Autorisierungsservice, ob der Nutzer das Angebot überhaupt nutzen darf.

Letzteres hat ein stark verkettetes Microservice-Konstrukt zur Folge, da jede Microservice-Anfrage zu einer Anfrage an den Autorisierungsservice führt. Bei einem Ausfall des Services oder zeitlichen Verzögerungen sind die Auswirkungen aufgrund des schlechten Designs überall zu spüren.

Auth Calls innerhalb einer monolithischen Infrastruktur sind kein Problem (Abb. 1) ...
Auth Calls innerhalb einer monolithischen Infrastruktur sind kein Problem (Abb. 1) ...
... im Microservice-Fall kommen allerdings Latenz und Ausfallrisiko dazu (Abb. 2).
... im Microservice-Fall kommen allerdings Latenz und Ausfallrisiko dazu (Abb. 2).

Hier braucht es eine Lösung, die ein zuverlässiges Prüfen der Autorisierung erlaubt, ohne weitere Aufrufe zu benötigen.

JWT: Header, Payload & Signatur

An der Stelle können die JSON Web Tokens (JWT) den Unterschied ausmachen. Sie bestehen aus drei Teilen: Header, Payload und Signatur. Im Header enthält der JWT den Typ des Tokens sowie den genutzten Hashing-Algorithmus. Dieser liegt Base64-kodiert vor; genau wie der Payload. Letzterer enthält die Autorisierungsinformationen über den Nutzer und typischerweise seine Rechte sowie seine Namen. Darüber hinaus ist es sinnvoll, eine Gültigkeitsdauer im Payload mitzuschicken.

Die Signatur wird benötigt, um die Echtheit des Tokens zu verifizieren. Sie besteht aus kodiertem Header, Payload und Secret, das die Signatur des Autorisierungsservice ist, um so die Echtheit des Tokens überprüfen zu können.

oAuth2 "pur": Tokens müssen gegen Resource Server verifiziert werden
oAuth2 "pur": Tokens müssen gegen Resource Server verifiziert werden
OAuth2 mit JWT: Tokens lassen sich mit Public Key dezentral verifizieren (Abb. 4).
OAuth2 mit JWT: Tokens lassen sich mit Public Key dezentral verifizieren (Abb. 4).

Da andere Microservices das Token anhand der Signatur verifizieren können, gibt es nach dem Login fast keine Calls an den Autorisierungsserver mehr. Das Signieren lässt sich mit einem "Private Public Key"-Verfahren durchführen. Dadurch müssen andere Microservices lediglich den Code zur Signaturprüfung enthalten und den Public Key kennen. Da das Token als Bearer Token im Autorisierungs-Header mitgesendet wird, können die Microservices ihn auswerten. Dank der Signatur gibt es keine Beschränkungen auf URLs. Das erlaubt auch Cross Site Authorization, was wiederum die Einmalanmeldung, den Single Sign-On (SSO), unterstützt und für den User von großem Interesse ist.

JWT Flow im Detail

Zunächst muss sich ein Nutzer beim Autorisierungsservice mit seinen Anmeldedaten einloggen. Da kann entweder per SSO oder klassischem Login passieren. Der Autorisierungsservice überprüft nun die Anmeldedaten und erstellt ein neues JWT. Der Code zum Erstellen eines JWT inklusive der Signiervorgang mit dem RS256-Algorithmus könnte in Java folgendermaßen aussehen:

public String createJwt(User loggedInUser) {
JwtBuilder builder = Jwts.builder()
.setSubject(loggedInUser.getUsername())
.claim("payload", loggedInUser.getPayload())
.setId(loggedInUser.getId())
.setExpiration(calculateExpirationTime());

return builder.signWith(
SignatureAlgorithm.RS256, privateKey
)
.compact();
}

Hier wird als Subject der Name des Nutzers und mit der claim-Methode der Payload des Nutzers für die Autorisierungsinformationen gesetzt. Danach legt das Programm eine eindeutige ID fest, anhand derer sich das Token jederzeit identifizieren lässt. Als Letztes definiert man ein Ablaufdatum.

Vor dem Zurückgeben des Token wird es noch mit dem Private Key signiert und in einen kompakten String serialisiert. Alle hier benutzten JWT-Methoden stammen aus dem Package io.jsonwebtoken, das sich bequem im Java-Projekt einbinden lässt. Libraries existieren für nahezu alle gängigen Programmiersprachen, sodass die Integration relativ einfach ist.

Nun kann die Anwendung das kompakte Token, das im folgenden Listing zu sehen ist, im Authorization Header des Browsers mitschicken, um sich gegenüber der Webseite zu authentifizieren – die einzelnen Teile des JWT sind mit Punkten getrennt – in der Form Header.Payload.Signatur:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

Auf der Seite der Microservices ist nun die Signatur des Tokens zu prüfen, um zu sehen, dass es überhaupt valide ist. Das Ablaufdatum sollte natürlich auch überprüft werden. In Java ist das im Prinzip der folgende Programmcode:

Claims claims = Jwts.parser()
.setSigningKey(publicKey)
.parseClaimsJws(accesTokenString)
.getBody();

Der Parser verifiziert, dass das Token im gültigen Format vorliegt, und prüft in der parseClaimsJws-Methode, ob es korrekt signiert und noch gültig ist. Der Microservice kann jetzt davon ausgehen, dass der Nutzer legitim ist und ihn als vertrauenswürdig einstufen.

Ein veranschaulichter Auth-Flow zwischen Microservices (grün) und der UI (blau) (Abb. 5)
Ein veranschaulichter Auth-Flow zwischen Microservices (grün) und der UI (blau) (Abb. 5)

Nachdem gezeigt wurde, wie einfach sich ein JWT erstellen und auslesen lässt, sollten allerdings noch einige Rahmenbedingungen erläutert werden, die es einzuhalten gilt. Die Menge an Payload im Token darf eine gewisse Länge nicht überschreiten, um eine Limitierung durch den Browser oder Server zu vermeiden (Apache hat hier zum Beispiel ein Standardlimit von 8 KByte). Auch sollten Tokens ein Ablaufdatum haben, da ansonsten das Entziehen von Nutzerrechten nahezu unmöglich wird. Zu guter Letzt sollten sie keine sicherheitskritischen Informationen wie Passwörter enthalten. Diese wären lediglich mit Base64 kodiert und ließen sich somit von jedem User dekodieren und auslesen.

SAML zu umfangreich und SWT zu anfällig

JWTs sind nicht die einzige Möglichkeit, Nutzer im Web- und Microservice-Kontext zu authentifizieren. Alternativ lässt sich die Security Assertion Markup Language (SAML) verwenden. Sie ist jedoch ein XML-Format und hat somit sprachbedingt ein deutlich umfangreicheres Datenvolumen, was sich vor allem auf mobilen Endgeräten negativ auswirkt. Dafür kann SAML mit asymmetrischen Signaturverfahren wie "Private Public Key Pair" agieren. Allerdings ist XML durch die digitale Signatur komplex und im Vergleich mit JSON schwieriger in Objekte umzuwandeln.

Eine weitere Möglichkeit sind Simple Web Tokens (SWT). Sie können allerdings nur durch symmetrische Signierungsverfahren geprüft werden. Das erhöht die Anfälligkeit für Hackerangriffe. Denn sobald ein Microservice gehackt ist, ist das Secret bekannt und das ganze System kompromittiert. Bei JWT kennt nur der Autorisierungsservice das Secret – und dieser einzelne Service lässt sich besser schützen als eine Vielzahl.

Überwältigende Vorteile

Im Vergleich zu anderen Optionen überwiegen bei JWT die Vorteile: die einfache Integrierbarkeit in viele Programmiersprachen, die zuverlässige Authentifizierung bei gleichzeitigem Reduzieren des Netzwerk-Overheads, die Nutzbarkeit im SSO-Fall sowie bei Login-Autorisierungen. Zusätzlich haben die JWTs verglichen mit SAML-Anwendungen den deutlich kleineren Footprint. JSON Web Tokens scheinen demnach für die Nutzer-Authentifizierung in einer Microservice-Umgebung die geeignetste Variante zu sein.

Weitere Informationen zu JSON Web Token finden sich auf der JWT-Website sowie im RFC7519. (ane)

Bernd Schönbach
ist seit über 10 Jahren in der Webentwicklung tätig. Zunächst in der PHP-Entwicklung im TYPO3-Umfeld. Mittlerweile entwickelt er mit Java Microservices.

3 Kommentare

Themen: