Suche
Authentifizieren - Einmal und nie wieder

Single Sign-on für Microservices und verteilte Anwendungen

Niko Köbler

© iStockphoto / Yokeetod

Anwender sicher zu authentifizieren und zu autorisieren, ist gerade in Microservices-Architekturen oder verteilten Anwendungen keine leichte Aufgabe. Vor allem, weil hier ein Securityknackpunkt liegt. Das Konzept Single Sign-on soll möglichst viel Sicherheit mit möglichst viel Bequemlichkeit für die Anwender verbinden. Verschiedene Technologien versuchen, das unter einen Hut zu bekommen.

Durch den anhaltenden Trend zu mehr verteilten Systemen und die in vielen Bereichen etablierten Microservices-Architekturen steigt mittlerweile – zum Glück – wieder das Interesse an Sicherheit in diesen Umgebungen. Anwendungssicherheit ist ein weites Feld mit unterschiedlichen Teilgebieten, am bekanntesten sind sicherlich die OWASP-Top-10-Angriffsszenarien.

Um alle möglichen Angriffe auf eine Applikation abzuwehren, sind unterschiedliche Mechanismen und Vorgehensweisen notwendig, die teils dezentral in allen Anwendungen oder Microservices selbst implementiert oder gelöst werden müssen, teils aber auch zentral abgebildet werden können oder sogar müssen. Das Teilgebiet der Sicherheit hinsichtlich Authentifizierung und Autorisierung ist meines Erachtens ein Thema, das nur zentral gelöst werden kann. Denn auf der einen Seite möchte man nicht in jeden Microservice oder in jede Anwendung im Unternehmensumfeld den gleichen Mechanismus einbauen und schlimmstenfalls per Copy and Paste Fehler weiterverbreiten, und andererseits reduziert man durch eine zentrale Lösung mögliche Angriffs- oder Datenabgriffspunkte. Schnell sind wir so also bei einer Single-Sign-on-(SSO-)Lösung, bei der ein Anwender seine Credentials nur an einer zentralen Stelle eingeben muss.

SSO bedeutet nämlich nicht unbedingt, dass der User sich nur ein einziges Mal authentifizieren muss, um mit allen Anwendungen und Services zu arbeiten – präziser heißt SSO, dass der User sich nur an einer einzigen Stelle authentifizieren darf. Dabei muss natürlich sichergestellt werden, dass Mechanismen zur Verteilung und Weitergabe der Identität und weitere so genannte Assertions oder Claims an die beteiligten Anwendungen existieren. Diese Vorgaben und Mechanismen sind identisch sowohl für verteilte Microservices als auch für mehrere monolithische Anwendungen im Unternehmensumfeld.

Authentifizieren oder autorisieren?

Ein Exkurs in die Begriffserklärung, da die jeweilige Bedeutung vielen immer noch nicht klar ist:

Authentifizierung: Der Anwender muss sich identifizieren, um sicherzustellen, dass er derjenige ist, für den er sich ausgibt. Am einfachsten geschieht das mit einem Benutzernamen und einem Geheimnis, das nur er kennt (z. B. Passwort). Danach weiß die Anwendung oder das System, wer der aktuelle Benutzer ist.

Autorisierung: Mit der Autorisierung werden dem zuvor authentifizierten Anwender Rechte eingeräumt, bzw. wird der Durchführung einer oder mehrerer bestimmter Operationen zugestimmt. Man weiß also, wer der Benutzer ist und was er tun darf.

Einfach sicher

Immer wieder begegnen mir Aussagen und Anforderungen wie „Das muss so sicher wie möglich und gleichzeitig so einfach wie möglich sein“. Sicherheit und Einfachheit, oder sagen wir besser Bequemlichkeit, schließen sich insofern aus, als es keine Möglichkeit gibt, die hundertprozentige Sicherheit bei hundertprozentiger Bequemlichkeit bietet. Entweder das eine oder das andere, oder eben ein Kompromiss aus beidem. Letzteres ist auch meist im Einsatz, die Gewichtung geht aber zu Gunsten der Sicherheit. Dieses Sicherheitsbewusstsein muss zum einen in die Köpfe von uns Entwicklern einsickern, aber auch in die der Anwender. Es ist heutzutage einfacher denn je, in schlecht abgesicherte Anwendungen einzudringen oder Daten von Benutzerkonten abzugreifen und zu missbrauchen. Ein Passwort namens „Passwort“ ist keine Sicherheit. Sonderzeichen und Zahlen als Ersatz oder zusätzlich zu Buchstaben ist für leistungsfähige Algorithmen ebenfalls keine Hürde mehr. Der einzige Weg, um es diesen Angreifern zu erschweren, unbefugt ins System einzudringen, sind ausreichend lange Passwörter, gerne auch ganze Sätze. Diese sind technisch schwer zu erraten und zu knacken, aber für uns Menschen relativ leicht zu merken. Aber zurück zum Thema: Versuchen wir, einen möglich guten Kompromiss aus Sicherheit und Einfachheit zu finden.

Kein Kompromiss ist es sicherlich, wenn jede Anwendung ihre eigene Benutzerauthentifizierung mitbringt. Dies führt schnell zu einem Log-in-Fensterwahn wie in Abbildung 1 zu sehen. Verschiedene Anwendungen verlangen unterschiedliche Authentifizierungsinformationen, z. B. Benutzername, E-Mail-Adresse oder Telefonnummer, zudem ein Passwort und vielleicht noch eine weitere Mehrfaktorenauthentifizierung. Der Anwender muss sich also viele unterschiedliche Dinge merken, wozu er in seiner gewohnten Bequemlichkeit selten bereit ist. Passwörter auf Post-its am Monitor oder Standardpasswörter sind die Folge, oder Anwender, die keine mehr sind, da sie nicht bereit sind, mit der Anwendung zu arbeiten. Und das ist aus Anbietersicht sicherlich nicht gewollt.

koebler_sso_1

Abb. 1: Verschiedene Log-in-Masken und -Fenster mit unterschiedlichen Anmeldeinformationen (Quelle: Facebook, Amazon, Stack Overflow, Google, GitHub, Twitter)

OAuth 2.0 und OIDC

Aus diesen Anforderungen heraus sind OAuth und dann der Nachfolger OAuth 2.0 entstanden. OAuth 2.0 ermöglicht es einem Nutzer einer Webanwendung, Zugriff auf ein API eines anderen Systems zu erlauben, ohne dass die Webanwendung Benutzername und Passwort des API kennt. Beispielhaft kann ein Nutzer es Facebook auf diese Weise ermöglichen, die Posts dort auch automatisch bei Twitter zu veröffentlichen, ohne dass bei Facebook Username und Passwort des Twitter-Accounts hinterlegt werden müssen. OAuth 2.0 definiert für unterschiedliche Szenarien verschiedene Autorisierungsflows, die dann von Implementierungen zur Verfügung gestellt werden; OAuth 2.0 ist seit 2012 über RFC 6749 im IETF-Standard veröffentlicht.

Es ist aber nur ein Autorisierungswerkzeug – grundlegende Benutzerinformationen fehlen bewusst, und eine Authentifizierung ist damit nicht möglich. Deshalb wurden in der Vergangenheit von vielen Internetunternehmen, wie Facebook und Amazon, OAuth-2.0-Add-ons entwickelt, um auch eine Benutzerauthentifizierung durchführen zu können. Leider waren diese Ansätze aber proprietär und konnten so von keiner anderen Anwendung genutzt werden. Aufgrund der Anforderung, andere Systeme auch als Authentifizierungssystem zu verwenden, hat sich OpenID Connect (OIDC) in der OpenID Foundation entwickelt, das 2014 als Standard verabschiedet wurde. OIDC ist ein auf OAuth 2.0 basierender Authentifizierungslayer und hat mit purem OpenID nichts zu tun. Einer seiner großen Vorteile ist es, dass damit auch für native Mobile-Apps, JavaScript-basierte Single-Page-Web-Apps und andere APIs ein sicherer Authentifizierungsflow möglich ist, ohne dass Client Secrets bekannt sein müssen. OIDC stellt zusätzlich zur Authentifizierung Profilinformationen des eingeloggten Users zur Verfügung, die über ein REST-ähnliches API abgefragt werden können.

Was ist mit SAML und Co.?            

SAML ist ein mächtiges und sicheres Protokoll, um Anwender zu authentifizieren und zu autorisieren. Einige Application-Server implementieren SAML sogar und stellen so die Verwendung direkt zur Verfügung. Allerdings ist SAML sehr komplex. Die häufig verwendete Kombination mit X.509-Zertifikaten macht die Sache nicht leichter, und es gibt auch keine Unterstützung der Anforderungen moderner Anwendungsarchitekturen. Da der SAML-Standard aus dem Jahr 2005 stammt, ist das nicht weiter verwunderlich.

Die Lösung: Tokens

All diese Lösungen sind also zu begrüßen und helfen in der Bewältigung der Anforderungen. Facebook, Twitter, Google und Co. arbeiten ja alle sehr erfolgreich damit. Aber sollen wir jetzt alle unsere Nutzerdaten diesen Unternehmen zur Verfügung stellen? Abgesehen davon, dass diese Unternehmen schon mehr von uns wissen, als uns lieb sein kann, ist das eher keine Option. Und die Anbindung unseres Unternehmens-LDAPs, -ADs oder weiterer Verzeichnisse finden Google und Facebook sicherlich toll, wir möchten sie aber doch vermeiden.

Also doch selbst implementieren? Schon wieder eine Log-in-Maske, schon wieder solche Dinge wie „Passwort vergessen“, „Registrierung“ und „Remember me“ implementieren? Irgendwie klingt das frustrierend und nicht nach viel Spaß bei der Entwicklungsarbeit. Und wie machen wir es in verteilten Umgebungen? In unserer monolithischen Anwendung bekommen wir das ja noch hin. Aber wie stellen wir sicher, dass alle beteiligten Systeme in verteilten Anwendungslandschaften die richtigen Informationen bekommen, ohne dass alle noch einmal einen aufwändigen und latenzbringenden Überprüfungsmechanismus implementieren müssen? Zumal so etwas wieder zu ungewollter Redundanz und möglichen Fehlerquellen führt. Was ist mit Offlinemöglichkeiten, da mobile Apps gegebenenfalls nicht immer über eine Internetverbindung verfügen? Und diese REST-only-Anwendung, die dem Benutzer ja gar keine Log-in-Maske zur Verfügung stellen kann? Fragen über Fragen überraschen uns plötzlich.

Lesen Sie auch: “Auch bei Microservices kann man Security zentral abbilden” – Interview mit Claus Straube

Die Lösung kommt in Form von Tokens. Ein Token ist in unserem Zusammenhang ein Datum, das in irgendeiner Art und Weise etwas über den Anwender oder dessen Rechte aussagen kann. Entweder direkt im Token oder indirekt, indem das Token nur einen Schlüssel darstellt und die Informationen selbst z. B. in einer Datenbank stehen. Das SAML-Token ist eines der bekanntesten Tokens, aber auch OAuth 2.0 arbeitet mit Tokens, dem Bearer Token. Ein Token sollte zustandslos sein und alle benötigten Informationen enthalten, also möglichst Authentifizierungs- und auch Autorisierungsinformationen. Weiterhin sollte ein Token die Integrität seiner Daten sicherstellen können, z. B. mit einer Signatur, mit der die Daten im Token überprüft werden können, um sicherzustellen, dass sie auf dem Transportweg von Anwendung A nach Anwendung B nicht kompromittiert wurden.

JSON Web Token hat sich etabliert

In Verbindung mit OAuth 2.0 und OIDC hat sich in den letzten Jahren das JSON Web Token (JWT) etabliert, das 2015 im IETF unter RFC 7519 zum Standard erklärt wurde. Das JWT ist, wie der Name schon sagt, im JSON-Format aufgebaut, besteht aus drei Teilen und ist für die einfache Übertragung als Text mit dem Base64-Algorithmus verschlüsselt. Abbildung 2 zeigt den JWT-Debugger der JWT-Website. Auf der linken Seite ist das Base64-verschlüsselte Token zu sehen, auf der rechten Seite die entschlüsselten Daten. Das verschlüsselte Token trennt die drei Teile jeweils mit einem Punkt voneinander. Der erste Teil, der Header, enthält die Informationen über den Algorithmus, mit dem das Token signiert ist, und von welchem Typ es ist (hier: JWT). Der zweite Teil, die Payload, enthält die eigentlichen Daten. Hierbei gibt es keine Beschränkungen oder Vorgaben. Bestimmte Daten für die Verwendung mit OAuth 2.0 und OIDC haben zwar Vorgaben, diese sind aber nur in der Verwendung mit OAuth 2.0 und OIDC vorgeschrieben. Wird das JWT für andere Anwendungsbereiche genutzt, können auch beliebige Felder verwendet werden. Der dritte Teil des Tokens beschreibt die Signatur des Tokens, die aus einer Kombination von verschlüsselten Header- und Payload-Daten mittels dem im Header angegebenen Algorithmus und einem Secret oder öffentlichem Schlüssel (Public Key) erstellt wird. Somit lässt sich die Integrität des Tokens jederzeit sicherstellen und überprüfen.

Abb. 2: JWT Debugger mit Base64-codiertem Token (links) und decodierten Informationen (rechts) (Quelle: https://jwt.io)

Abb. 2: JWT Debugger mit Base64-codiertem Token (links) und decodierten Informationen (rechts) (Quelle: https://jwt.io)

OAuth 2.0 beschreibt ein Access- und ein Refresh-Token. OIDC verwendet das Identity-Token. Das Identity-Token stellt, wie der Name schon sagt, die Identität des Anwenders, also User- und Real Name sowie gegebenenfalls weitere Profilinformationen zur Verfügung. Das Access-Token ist in OAuth 2.0 notwendig, um die Zugriffe auf eine bestimmte Ressource zu autorisieren. Im Zusammenhang mit dem JWT enthält das Access-Token auch die Informationen aus dem Identity-Token, sodass meist nur das Access-Token für Ressourcenzugriffe notwendig ist. Geht es nur um die Identität des Anwenders, genügt logischerweise das Identity-Token. Jedes Token hat eine begrenzte Lauf- bzw. Lebenszeit. Gerade ein Access-Token sollte eine geringe Laufzeit haben. Bei dessen Überprüfung muss eine Anwendung auch den Gültigkeitszeitraum überprüfen und den Zugriff verwehren, wenn das Token abgelaufen ist. Ein reiner Signaturcheck ist nicht ausreichend. Ist das Access-Token nicht mehr gültig, kommt das Refresh-Token zum Einsatz. Es hat eine lange Laufzeit, und mit ihm können neue Access-Tokens ausgestellt werden. Das Refresh-Token ist also entsprechend sensibel zu behandeln. Die Tokens werden im der OAuth-2.0-basierten Kommunikation im HTTP Request als Authorization Header im Bearer-Token-Schema versendet:

    Authorization: Bearer eyJhbGciOiJIUzI...

Auf Empfängerseite kann das Token dann ohne nochmaligen Roundtrip zum ausstellenden Server überprüft werden, sofern das Secret (HMAC-Algorithmus) oder der Public Key (RSA) vorliegen. Da der Empfänger (der Client) auch den ausstellenden Server kennen muss, hat der Empfänger im Allgemeinen Informationen über den Server vorliegen und kann das Token nicht nur über die Signatur, sondern zusätzlich mit Daten wie dem ausstellenden Server, dem Gültigkeitsraum (Realm) und der Lebenszeit des Tokens überprüfen. Ist wegen erhöhter Sicherheitsanforderungen eine so genannte Onlineüberprüfung beim ausstellenden Server notwendig, geht auch das, erzeugt aber zusätzlich Latenz in der gesamten Kommunikation. Das kann bei einem hohen Request-Aufkommen zu spürbaren Verzögerungen und Einschränkungen führen. Die JWT-Website [4] führt für viele unterschiedliche Sprachen bereits vorhandene Bibliotheken auf, die mit den einzelnen Anforderungen der JWT-Spec unterschiedlich gut umgehen können.

SSO in der Java-Welt

Wir möchten jetzt also gerne mit OIDC, OAuth 2.0 und Tokens in unserer Java-basierten Web- oder Microservices-Anwendung arbeiten. Schauen wir uns einmal verschiedene Standards und Bibliotheken (oder Frameworks) dazu genauer an.

Leider bietet der Java-EE-Standard bislang hier keine passende Unterstützung hinsichtlich der APIs. Man könnte sagen, dass Java EE auch an dieser Front den Zug verpasst hat. Außer JAAS (Java Authentication and Authorization Service) bietet sich hier keine Lösung aus dem Standardbaukasten an, und JAAS bietet keine Unterstützung für die genannten Anforderungen. Aber immerhin ist momentan (Stand Mitte November 2016) für Java EE 8 das Java EE Security API JSR-375 geplant. Doch wer weiß, wie es wirklich mit Java EE weitergeht.

Das Spring-Ökosystem bietet mit Spring Security eine gute und umfangreiche Unterstützung verschiedener Authentifizierungs- und Autorisierungsmethoden, so auch für OAuth 2.0, und eine tokenbasierte Autorisierung. Die Voraussetzung ist hier allerdings die Nutzung von Spring mit oder ohne Boot als Applikationsbasis.

Viele Entwickler greifen gerne zu Apache-Bibliotheken, wenn sie keine Unterstützung aus der von ihnen gewählten Basis bekommen. Mit Apache Shiro steht eine sehr bekannte Bibliothek zur Verfügung. Allerdings unterstützt Shiro weder OAuth 2.0 noch OIDC. Somit kommt dieser Ansatz eher weniger für unsere Anforderungen in Frage. Apache Oltu ist eine eher weniger bekannte Bibliothek, die aber OAuth 2.0, OIDC und auch JWT unterstützt. Ich selbst habe mit Oltu leider gar keine Erfahrung, und auch die Recherche im Netz bringt vergleichsweise wenige Einträge hervor, sodass jeder, der Oltu einsetzen möchte, sich genau überlegen sollte, ob er mit den zur Verfügung stehenden Ressourcen ausreichend versorgt ist.

Mit pac4j existiert eine sehr umfangreiche Security Bibliothek, die unterschiedliche Authentifizierungs- und Autorisierungsmethoden unterstützt und zusätzlich Integrationen oder Adapter für viele aktuelle und bekannte Webframeworks bietet. Eine sicherlich interessante und lohnenswerte Alternative, die man sich anschauen sollte.

Security-as-a-Service bzw. Auth*-as-a-Service haben verschiedene Anbieter im Portfolio. Auth0 ist sicherlich einer der bekanntesten Anbieter, die Authentifizierung und Autorisierung für mich übernehmen können und wo ich nur noch die Integration in meine Anwendung vornehmen muss; meist mit von den Anbietern zur Verfügung gestellten Bibliotheken. Amazon Cognito und Stormpath als Alternativen sind dem einen oder anderen Leser sicherlich bekannt. Was allerdings diese Serviceanbieter gemein haben, ist, dass ich entweder meine Userdaten in die Hände – bzw. die Datenbanken – der Anbieter legen muss oder den Anbietern Zugriff auf mein Unternehmensverzeichnis und damit auf das Unternehmensnetz geben muss. Ob man das immer möchte und ausreichend absichern kann, muss jeder im Einzelfall prüfen und entscheiden.

Flexibel sein mit Keycloak

Mit Keycloak stellt JBoss eine integrierte Single-Sign-on und Identity-Access-Management-(IAM-)Lösung für Browseranwendungen und RESTful Web Services zur Verfügung. Das Projekt existiert seit 2013 und ist offizieller Nachfolger des PicketLink-Projekts. JBoss-typisch wird das Projekt also Open-Source-Software bei GitHub gehostet und entwickelt. Durch die offene Kommunikation erfreut sich Keycloak einer großen und sehr aktiven Community, die sich nicht nur auf den Mailinglisten bemerkbar macht, sondern auch viele gute Contributions zum Projekt selbst beiträgt. Seit etwas mehr als einem Jahr erscheinen regelmäßige Feature- und Bugfix-Releases, meist im Abstand von vier bis sechs Wochen, sodass potenzielle Sicherheitslücken für die Allgemeinheit schnell geschlossen werden können. Die Dokumentation ist, JBoss-typisch, sehr gut und umfangreich.

Möchte man Keycloak testen, empfiehlt es sich, zunächst die Demodistribution runterzuladen. Diese kommt entsprechend vorkonfiguriert und mit einigen Integrations- und Erweiterungsbeispielen, sodass man sie einfach nur starten und sofort loslegen kann. Für den produktiven Einsatz ist diese Version sicherlich nicht geeignet. Hier sollte die Stand-alone-Serverdistribution verwendet werden, bzw. ein Overlay für einen bestehenden WildFly/EAP-Server, das Docker Image oder auch der gehostete OpenShift-Cloudservice. Ein Overlay für existierende Server ist nur für WildFly bzw. JBoss EAP verfügbar. Das hängt damit zusammen, dass Keycloak hier von ein paar JBoss-nativen APIs – vor allem Infinispan – Gebrauch macht, die auf anderen Servern naturgemäß nicht zur Verfügung stehen. Das heißt aber nicht, dass Keycloak nicht auf anderen Server laufen kann. Tests und PoCs aus der Community zeigen, dass Keycloak sogar als Spring-Boot-Anwendung betrieben werden kann. Seit einiger Zeit wird von Red Hat eine Version mit Support unter dem Namen Red Hat Single Sign-On angeboten, für alle diejenigen, die gerne Support in Anspruch nehmen möchten.

Mehr zum Thema: JAX TV – Microservices ohne Esoterik

Keycloak kommt mit jeder Menge Features hinsichtlich Authentifizierung und Autorisierung: Zu Single Sign-on gesellt sich auch eine Single-Sign-out-Option. Die üblichen Dinge wie „Forgot Passwort“, „Remember me“, „Self-Registration“ und „Verify User/E-Mail“ gibt es out of the Box. Dazu gesellen sich Features wie Two-Factor Authentication (TOTP) und die Möglichkeit, LDAP bzw. AD als Federation-Provider zu konfigurieren. Auch andere Verzeichnisse oder Tabellen als Userquelle anzubinden, ist möglich, indem man eines der vielen zur Verfügung stehenden Serviceproviderinterfaces (SPI) ausprogrammiert. Das ist nicht wirklich aufwändig. Da Keycloak eine volle OAuth-2.0- und OIDC-Unterstützung – Keycloak ist sogar OIDC zertifiziert – mitbringt, ist natürlich auch die Einbindung von Social-Providern wie Facebook, Google oder Twitter möglich. Abbildung 3 zeigt ein Log-in-Formular mit allen möglichen aktivierten Identity-Providern, die bereits mitgeliefert werden. Das Look and Feel der gesamten Keycloak-Masken (Log-in, Registrierung, Accountmanagement etc.) lässt sich über Templates vollständig an das Unternehmens-CI anpassen. Wer nicht mit OIDC arbeiten möchte und lieber dem guten alten SAML den Vorzug gibt, der konfiguriert Keycloak einfach für die Verwendung mit SAML, denn auch das ist kein Problem.

koebler_sso_3

Abb. 3: Keycloak-Standard-Log-in-Formular mit allen aktivierten Optionen

 

Die bereits erwähnten SPIs machen Keycloak sehr flexibel für den Unternehmens- oder Projekteinsatz. Über das User-SPI können bereits existierende Verzeichnisse, Anwendungen oder Tabellen als Quelle für Benutzerdaten integriert werden. Soll ein anderer Authentifizierungsflow als die existierenden verwendet werden, z. B. eine Mehrfaktorauthentifizierung mittels SMS, lässt sich das über das Authentication SPI realisieren. Da Keycloak Events auch über das Event-SPI publizieren kann, kann darauf in einer SPI-Implementierung reagiert werden. Wenn ein User z. B.versucht, sich mehrfach mit ungültigen Daten anzumelden, kann eine weitere, eigene Aktion aufgerufen werden.

Apropos ungültige Anmeldedaten: Natürlich kann Keycloak auch auf Brute-Force-Angriffe reagieren und für die Sicherheit des Passworts mit entsprechenden Passwort-Policies konfiguriert werden, sofern die Passwörter von Keycloak verwaltet werden. Keycloak versendet nie ein Passwort, auch dann nicht, wenn ein Anwender sein Passwort vergessen hat. Es wird immer nur ein mit einer zeitlichen Gültigkeit versehener Link versendet, unter dem der Anwender sein Passwort wieder neu setzen kann.

Übersichtliche Architektur

Abbildung 4 gibt einen groben Überblick über die Architektur von Keycloak. Im Kern verwaltet Keycloak Realms, Clients, Rollen, User und Gruppen. Ein Realm ist ein Gültigkeits- bzw. Hoheitsbereich, in dem alle Clients, Rollen, User und Gruppen eindeutig sind. Ein Client kann nicht in mehreren Realms existieren, Rollen können global in einem Realm gelten oder auch nur für einzelne Clients; ein Client ist eine Anwendung, die über Keycloak abgesichert wird. User können in Gruppen zur vereinfachten Verwaltung zusammengefasst werden, ein User erhält seine Rollenzuordnung entweder direkt oder über eine Gruppe.

Abb. 4: Grobe Darstellung der Keycloak-Architektur

Abb. 4: Grobe Darstellung der Keycloak-Architektur

Keycloak persistiert standardmäßig die Daten entweder in einer klassischen relationalen Datenbank oder dokumentenbasiert in MongoDB. Ich denke, ich muss nicht erwähnen, dass man auch diesen Mechanismus gegen eine eigene Implementierung austauschen kann. Die AD/LDAP-, OIDC/SAML-Komponenten im unteren Abschnitt stellen beispielhafte externe Quellen für User- und Authentifizierungsdaten dar.

Web Tales

Niko Köbler

In der Kolumne Web Tales gibt Niko Köbler (freiberuflicher Software-Architekt) Anstöße zur Web-Entwicklung mit JavaScript, Java & Co. Aus der Praxis, für die Praxis!

Bisher erschienen:

Der obere Bereich stellt alle nach außen nutzbaren Schnittstellen dar. Zum einen die Authentifizierungsprotokolle OIDC und SAML, ein allgemeiner Infoendpunkt, von dem Clients die benötigten Registrierungsinformationen beziehen können, das Log-in- und Accountmanagement-Frontend, Admin-API und Admin-Konsole. Das Log-in-API ist aus guten Gründen nach außen nur über das Log-in-Frontend erreichbar. Schließlich soll ein Anwender seine Daten der Sicherheit wegen ja nur an einem bestimmten Punkt – das „Single“ in SSO – eingeben müssen, und alle anderen Anwendungen sollen die User-Credentials nicht zu Gesicht bekommen. Das Accountmanagement-API ist derzeit nur über das dazugehörige Frontend erreichbar. Über das Accountmanagement kann ein Anwender seine eigenen Daten (Name, Passwort, TOTP etc.) ändern. Es gibt immer mal wieder den Ansatz, hierfür ein REST-API zu Verfügung zu stellen, auch ein JIRA-Ticket existiert. Allerdings wird das alles immer wieder nach hinten geschoben. Einzig das Admin-API steht auch als REST-API zur Verfügung. Somit ist es möglich, die gesamte Keycloak-Verwaltung mittels des REST-API durchzuführen. Die Admin-Managementkonsole ist eine AngularJS SPA, die ebenfalls das Admin-API nutzt. Auch das Java-Admin-API und das sich im Aufbau befindende CLI nutzt das Admin-REST-Interface. Ich habe hierzu bereits vor ein paar Monaten ein Blogpost verfasst.

Einfach integriert

Die Integration von Keycloak als IAM- oder SSO-Lösung in die eigene Anwendung geschieht mittels so genannter Adapter. Bereits mitgeliefert werden derzeit Adapter für:

  • JBoss EAP (6,7)/WildFly (9, 10)
  • Tomcat (6, 7, 8)
  • Jetty (8.1.x, 9.x)
  • Spring Boot
  • Spring Security
  • JBoss Fuse
  • Apache Karaf
  • Servlet-Adapter (als Fallback für oben nicht aufgeführte Umgebungen)
  • JavaScript-Adapter

Natürlich ist es auch möglich, einen Adapter selbst zu implementieren. Weiterhin können OAuth-2.0-/OIDC-Drittbibliotheken verwendet werden. Oder falls man keine Möglichkeit hat, die Anwendung entsprechend zu modifizieren, kann man den Keycloak-Proxy verwenden, der die gesamte Absicherung der Anwendungspfade übernimmt und dann die Auth*-Informationen in den HTTP-Header zur hinter dem Proxy liegenden Anwendung einfügt. Beispielhafte Demointegrationen für Anwendungen, basierend auf Java EE, Spring Boot und JavaScript SPAs (mit ReactJS) liegen in meinem GitHub-Account.

Fazit

Verteilte Anwendungen und Microservices bedürfen einer erweiterten Absicherung hinsichtlich Authentifizierung und Autorisierung, als es einfache Anwendungen in der Vergangenheit getan haben. Auch den gewachsenen Ansprüchen hinsichtlich Single Sign-on muss Rechnung getragen werden. Spezifikationen wie OAuth 2.0, OpenID-Connect und JSON Web Token machen es heute möglich, diese Anforderungen recht einfach in die eigenen Anwendungen zu integrieren und weiterhin kompatibel mit anderen Systemen zu bleiben.

Lesen Sie auch: Microservices-Applikationen in der AWS Cloud

Leider ist die Java-Welt in einigen Teilen noch etwas hinter dem Trend zurück, gerade der Java-EE-Standard. Es gibt jedoch Ansätze, die das Leben hier deutlich erleichtern. Für mich ist Keycloak von JBoss eines der umfangreichsten und leistungsfähigsten Projekte. Der Featureumfang und die große Anzahl an implementierbaren Serviceproviderinterfaces machen Keycloak unheimlich flexibel in der Integration in die eigene Umgebung. Und mit den zur Verfügung stehenden Adaptern, nicht nur für Java-Anwendungen, werden Integration und Einsatz in den einzelnen Anwendungen ein Kinderspiel. Bislang habe ich Keycloak bei mehreren Kunden eingesetzt oder die Implementierung begleitet und kann nur von positiven Erfahrungen berichten. Meist gelingt eine erste (Demo-)Integration schon am ersten Tag. Es lohnt sich also auf jeden Fall, sich mit Keyclaok und damit einer vernünftigen SSO- und IAM-Lösung auseinanderzusetzen.

Geschrieben von
Niko Köbler
Niko Köbler
Niko Köbler ist freiberuflicher Software-Architekt, Developer & Trainer für Java & JavaScript-(Enterprise-)Lösungen, Integrationen und Webdevelopment. Er ist Co-Lead der JUG Darmstadt, schreibt Artikel für Fachmagazine und ist regelmäßig als Sprecher auf internationalen Fachkonferenzen anzutreffen. Niko twittert @dasniko.
Kommentare
  1. Axel Baumann2017-02-20 10:54:07

    Base64 ist keine Verschlüsselung! Es ist nur eine andere Darstellungsform.

  2. René Peinl2017-02-20 15:19:18

    Schöner Überblicksartikel, der viele wichtige Aspekte enthält. Ich bin jedoch etwas enttäuscht, dass nach der recht neutralen Darstellung verschiedener Möglichkeiten bzgl. Protokollen, Bibliotheken und SaaS Angeboten für Authentifizierung, dann doch recht einseitig auf Keycloak als IAM Tool herum geritten wird. Ja, ich finde das auch eine neue, interessante Alternative. Darüber sollten jedoch die etablierten Angebote wie CAS und OpenAM nicht vergessen werden.
    Von Auth0 und Stormpath gibt es übrigens auch Java Bibliotheken, um mit JWT umzugehen.
    https://github.com/auth0/java-jwt https://github.com/jwtk/jjwt
    Die sind nicht so umfangreich wie pacj4, aber manchmal sucht man ja eher eine schlanke Lösung. Zusammen mit einem JAX-RS ContainerFilter und einer eigenen Annotation kann man da sehr performant sicheren Zugriff auf RESTful Webservices realisieren.
    Weiterhin wären authentisierende API Gateways wie Tyk eine Erwähnung wert gewesen
    https://github.com/TykTechnologies/tyk

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.