Single Sign-On mit Keycloak als OpenID Connect Provider

2 Kommentare

Komfortables Single Sign-On in einer professionellen Identity- und Accessmanagement (IAM) Umgebung – und das auch noch Open Source? Keycloak als OpenID Connect Provider macht’s möglich.

Wen freut es nicht: Die täglich notwendige mehrfache Mehrfaktorauthentifizierung und das Gefühl von Sicherheit, das jede spezifische Eingabe von Benutzername und Passwort für die einzelnen Unternehmensanwendungen suggeriert? Dennoch mag es Menschen geben, die den Zeitverlust bei jedem einzelnen Login satt sind und denen schon lange keine neuen, sicheren Passwörter mehr einfallen. Für genau diejenigen ist die Unterstützung von Single Sign-On (SSO) die ersehnte Lösung. Bisher allerdings sind Identity- und Accessmanagement-Lösungen in Unternehmen meist noch spezifisch für einzelne Applikationen implementiert. Dies macht die Einführung von SSO ungleich schwieriger. Daher wird in vielen Unternehmen der Ruf nach “Identity as a Service”-Lösungen (IDaaS) lauter. Neben den offensichtlichen Vorteilen aus Anwendersicht hat die Einführung von einer unternehmensweiten IDaaS-Lösung auch aus der Sicht von Anwendungsentwicklern viele Vorteile. Unter anderem ermöglicht die Auslagerung einen effizienteren Entwicklungsprozess, da nicht jede Anwendung ein eigenes IAM implementieren muss. Außerdem ist es in fast allen Fällen sinnvoll, wenn solch sicherheitskritische Anwendungen wie ein IAM an einer zentralen Stelle verwaltet und nicht über viele Implementierungen in verschiedenen Anwendungen verteilt werden.

In einem ersten Blogpost dieser Serie hat Dieter Dirkes Keycloak als vielversprechendes IAM Tool vorgestellt, das alle Kriterien einer IDaaS-Plattform erfüllt. In diesem Blogpost sollen zunächst die nötigen Grundlagen für das Verständnis der Funktionalität von Single Sign-On (SSO) in einer professionellen IAM-Plattform erläutert werden. Dann wird gezeigt, wie Keycloak als OpenID Connect Provider (OP) für SSO zwischen Applikationen konfiguriert wird. Um den Komfort, den die Nutzung von Standardprotokollen bietet, motivieren zu können, nutzen wir das Open-Source-Apache-Modul mod_auth_openidc als Relying Party (RP), die als Reverse Proxy zwei Web-Anwendungen beschützt.

Die starke Verbreitung von Social-Login-APIs wie z.B. durch Facebook, Twitter oder Dropbox hat gezeigt, dass bei der Einführung von IDaaS-Lösungen der Einsatz von Standards wie OAuth 2.0 und OpenID Connect essentiell ist. Im Folgenden werden daher zunächst möglichst kurz die Grundlagen von OAuth 2.0 sowie darauf aufbauend von OpenID Connect vorgestellt, bevor auf die Implementierung von Keycloak als OP eingegangen wird.

OAuth 2.0

OAuth 2.0 ist ein offener Standard, der ausschließlich den authentifizierten Zugriff eines Benutzers auf eine Ressource behandelt. Es bietet keine Funktionalität zur Überprüfung der Identität. Dazu kommen wir erst mit OpenID Connect.

Generell erfolgt der authentifizierte Zugriff mit OAuth immer im Interesse von jemandem: Ich registriere mich in einer Applikation, im Folgenden Client genannt, die Neuigkeiten auf meinem Facebook-Profil veröffentlichen möchte. Der Client nutzt Facebook als OP und erfragt zunächst bei mir die spezifischen Rechte. Durch Eingabe meiner Facebook-Login-Daten autorisiere ich die Applikation, Posts auf meinem Profil veröffentlichen zu dürfen. Der Zugriff erfolgt also in meinem eigenen Interesse.

Abbildung 1: Ablauf einer Authentifizierung mit OAuth 2.0 [1]

Abbildung 1 beschreibt die Authentifizierung etwas detaillierter und führt die spezifischen Begrifflichkeit ein. Ein Access Token wird vom Client in jedem Request verwendet, um vom Authorization Server autorisiert zu werden. An dieser Stelle sieht man schon, welchen Vorteil OAuth mit sich bringt: Ein Client erhält nie direkt Benutzernamen und Passwort von einem Resource Owner. Um einem Client die Autorisierung zu entziehen, genügt es also, das entsprechende Access Token invalid zu setzen, ohne gleich den Benutzer auffordern zu müssen, sein Passwort zu ändern. In Abbildung 1 wird zwischen Authorization Server und Resource Server unterschieden. Wie allerdings schon am Beispiel von Facebook deutlich wird, ist diese Unterscheidung zumindest aus Sicht des Clients nicht immer notwendig.

Zunächst soll diese informelle Beschreibung von OAuth einmal ausreichen. OpenID Connect erweitert OAuth um einen Identity-Layer. Die reine Authentifizierung mit OAuth ist somit Teilmenge der vollständigen Funktionalität von OpenID Connect. Keycloak soll als OpenID Connect Provider konfiguriert werden, daher wird die Authentifizierung mit OpenID Connect im Folgenden etwas detaillierter betrachtet.

OpenID Connect

Seit dem 26. Februar 2014 als Standard anerkannt, ermöglicht OpenID Connect Web-SSO- und Cross-Domain-Identity-Verwaltung. Ein OpenID Connect Provider ist die zentrale Stelle zur Verwaltung eines Benutzerprofils und somit auch im Autorisierungsprozess die zentrale Komponente.

Abbildung 2: Authentifizierung mit OpenID Connect [2]

Abbildung 2 zeigt den Ablauf der Authentifizierung mit OpenID Connect. Der Browser ist die zentrale Komponente, der für die Kommunikation zwischen Client und OP verwendet wird. Wenn der Benutzer eine geschützte Resource anfragt und noch keine gültige Session vorliegt, wird er für einen (1) Auth Request zum OP weitergeleitet. Nach erfolgreicher (2) Authentifizierung, z.B. durch Eingabe von Benutzername und Passwort, erhält der Client den (3) Auth-Code. Der Auth-Code wird dann vom Client (4+5) direkt beim OP zu Access, Refresh und Identity Token ausgetauscht. Der Client identifiziert sich mit seiner ID und einem Secret, das initial bei der Erstellung des Clients in Keycloak erzeugt wird. Dieser spezifische Grant Authorization Flow kann nur für Anwendungen durchgeführt werden, denen zugetraut werden kann, das Secret sicher zu verwahren. Eine JavaScript-Anwendung beispielsweise würde einen anderen Flow verwenden müssen, da das Token nicht sicher verwahrt werden kann. Abschließend setzt der Browser die (6) Session.

Dieser initiale Prozess ist annähernd analog zu der Autorisierung mit OAuth. Lediglich der Response vom Server unterscheidet sich. Wie in OAuth erhält die RP ein Access und ein Refresh Token. Das access token hat eine kurze Lebenszeit und kann nach Ablauf mit dem refresh token erneuert werden. Zudem erhält die RP ein ID Token als Response, das als JSON Web Token (JWT) kodiert ist. Dieses enthält Attribute, die der Identität des Benutzers zugeordnet sind und von der Applikation verwendet werden können. Zudem können über Claims erweiterte Zugriffsrechte gesetzt werden.

Generell definiert OpenID Connect verschiedene Rest-Endpunkte, die die Funktionalität zur Verfügung stellen. Die so genannte well-known Konfiguration ist einer dieser Endpunkte, die für die automatische Discovery eines OP verwendet werden. Wir wollen nun nicht die Funktionalität jedes einzelnen Endpunktes beschreiben, da dies den Rahmen sprengen würde. Der well-known Endpunkt wird später allerdings noch einmal aufgriffen, da er für die Metadata-Konfiguration von mod_auth_openidc verwendet wird. 

Single Sign-On

Redirected eine RP nach erfolgreicher Anmeldung erneut zum OP, um die Authentifizierung zu prüfen, z.B. für einen weiteren Request, so muss der Benutzer natürlich seine Credentials nicht erneut eingeben. Die Session kann sowohl in einem flüchtigen als auch persistenten Cookie gespeichert werden. Dies erlaubt es, SSO zwischen allen RPs, die mit demselben OP kommunizieren, einzuführen.

Abbildung 3: Single Sign-On nach zuvor erfolgreicher Anmeldung [2]

Keycloak unterstützt demnach Federated SSO, d.h. SSO basierend auf dem Austausch von Token und nicht von Benutzername und Passwort. Das KEYCLOAK_IDENTITY Cookie enthält das ID Token des Benutzers und wird für SSO zwischen verschiedenen Applikationen verwendet. Bei einem Login prüft Keycloak zunächst, ob das KEYCLOAK_IDENTITY Cookie vorhanden und valide ist. Ist dies der Fall, ist dann kein Login mehr notwendig, sondern dem Benutzer wird direkt die Ressource präsentiert. Wie in Abbildung 3 illustriert, startet auch Client B mit einen (1) Auth Request. Der Unterschied zu dem Ablauf in Abbildung 2 ist, dass Client A bereits eine erfolgreiche Anmeldung durchgeführt und daher das KEYCLOAK_IDENTITY Cookie im Browser gesetzt ist. Der Benutzer muss sich demnach nicht erneut authentifizieren, sondern der Client erhält direkt den (2) Auth-Code. Der weitere Ablauf ist dann analog zu Abbildung 2.

Keycloak als OpenID Connect Provider einrichten

Die folgende Konfiguration von keycloak als OP präsentieren wir, um den Komfort zu motivieren, den IAM mit Keycloak mit sich bringt. Auf eine detaillierte praktische Implementierung werden wir im nächsten Blogpost eingehen. Wer bis dahin nicht warten kann, dem legen wir schon einmal die gute Dokumentation zu Keycloak ans Herz. Sie ist ein sehr guter Ausgangspunkt, um Keycloak Schritt-für-Schritt auf dem eigenen System zu starten.

In Keycloak muss zunächst ein Client angelegt werden, der für die Kommunikation mit einer Anwendung verwendet werden kann. Dieser Client repräsentiert also in Keycloak die jeweilige Anwendung, die Keycloak als OP verwenden möchte. Zuvor wurde schon bei der Beschreibung von OAuth der Begriff Client verwendet, um die Applikation zu beschreiben, die Zugriff auf geschützte Ressourcen erlagen will. Hieran erkennt man, wie eng Keycloak an den festgelegten Standards entwickelt wurde. Clients können im Keycloak separat verwaltet werden. Dies macht es beispielsweise möglich, Rechte anwendungsspezifisch zu verwalten. Abbildung 4 zeigt die Konfiguration des Clients im Keycloak-Administrator.

Letztlich ist es für eine initiale Konfiguration wichtig, dass wir als Client Protocol openid-connect wählen. Unser Proxy ist eine vertrauenswürdige Anwendung, daher kann als Access Type confidential gewählt werden. Dies ermöglicht die Identifizierung des Clients per ID und Secret in einem Request. Das Secret kann unter Credentials eingesehen werden. Die valid Redirect URIs ermöglichen eine erweiterte Sicherheitsprüfung. Ein Redirect darf nur zu URIs erfolgen, die als valid angegeben sind. In unserem Basis-Setup können wir diese spezifische Einstellung allerdings erst einmal vernachlässigen und alle URIs erlauben.

Client_setting

Abbildung 4: OpenID Connect Client in Keycloak hinzufügen und konfigurieren

Wir haben nun also einen Client angelegt, mit dem wir über OpenID Connect kommunizieren können. Im Folgenden wollen wir nun zeigen, wie wir das Apache-Modul mod_auth_openidc nutzen, um zwei einfache Webseiten zu beschützen.

mod_auth_openidc konfigurieren

Das Open-Source-Apache-Modul mod_auth_openidc ermöglicht eine sehr komfortable Nutzung von OpenID Connect für einen Reverse Proxy. Auch hier setzen wir wieder voraus, dass bereits ein Apache HTTP Server installiert und initial konfiguriert ist. Wir nutzen die Proxy-Funktionalität und stellen im Folgenden das minimale Setup des Reverse Proxy vor:

Listen 443
User 443
Group www
DocumentRoot <path>
ErrorLog "logs/error_log"
LogLevel info
ServerName am proxy

LoadModule ssl_module modules/mod_ssl.so
LoadModule auth_openidc_module modules/mod_auth_openidc.so

<VirtualHost _default_:443>
  SSLEngine on
  SSLCertificateFile <path>
  SSLCertificateKeyFile <path>
  SSLCertificateChainFile <path>

  OIDCProviderMetadataURL http://amserver:8080/auth/realms/master/.well-known/openid-configuration

  OIDCClientID apache-proxy
  OIDCClientSecret <client_secret>

  OIDCRedirectURI https://amproxy/protected

  <Location "/protected">
    AuthType openid-connect
    Require valid-user
  </Location>

  <Location "/app1">
    AuthType openid-connect
    Require valid-user
  </Location>

  <Location "/app2">
    AuthType openid-connect
    Require valid-user
  </Location>

</VirtualHost>

Zugriffe auf die Pfade /app1 sowie /app2 werden beschützt. Die Require-Klausel kann genutzt werden, um zusätzliche Autorisierung zu prüfen. Beispielsweise die Zugehörigkeit zu einer bestimmten Gruppe. In unserem Beispiel allerdings reicht ein erfolgreicher Login aus, um Zugriff auf die beschützte Ressource erlangen zu können. Wie zu Beginn schon angemerkt, erfolgt die Konfiguration von OpenID Connect sehr komfortabel durch die Angabe der well-known Konfiguration für die OIDCProviderMetadataURL. Sowohl die OIDCClientID als auch das OIDCClientSecret beziehen sich auf den Client, den wir zuvor im Keycloak angelegt hatten. Die OIDCRedirectURI muss eine URI sein, die beschützt ist. Über diese URI erfolgt z.B. der Logout der Session.

Natürlich sind dies nur sehr rudimentäre Einstellungen. mod_auth_openidc ist ein stark konfigurierbares Modul, das einen eigenen Blogpost verdient. Dennoch wollen wir hiermit zunächst diesen Blogpost abschließen und die vollständige Konfiguration von mod_auth_openidc in einem späteren Blogpost aufgreifen. 

Wir haben in diesem Blogpost die rudimentären Grundlagen von OAuth und OpenID Connect vorgestellt. Diese sind essentiell, um den Ablauf von Federated SSO verstehen und IAM-Anwendungen einführen zu können. Zudem wollten wir zeigen, inwieweit Keycloak zusammen mit mod_auth_openidc den Einsatz dieser komplexen Protokolle vereinfacht. Unserer Erfahrung nach ist Keycloak eine sehr mächtige IAM-Lösung, die durch ein hohes Maß an Flexibilität und Komfort eine Integration in eine bestehende Infrastruktur stark vereinfacht. Auf die genaue praktische Implementierung werden wir im nächsten Blogpost eingehen.

[1] Spasovski, Martin. OAuth 2.0 Identity and Access Management Patterns. Packt Publishing Ltd, 2013.
[2] Siriwardena, Prabath. Advanced API Security: Securing APIs with OAuth 2.0, OpenID Connect, JWS, and JWE. Apress, 2014.

Weitere Posts dieser Serie:

1 – Accessmanagement mit Keycloak
2 – Single Sign-On mit Keycloak als OpenID Connect Provider

Jannik Hüls

Jannik unterstützt seit 2016 das codecentric Team in Münster. Er beschäftigt sich mit der technischen Umsetzung von IT-Architekturen und der Integration von Anwendungskomponenten. Aktuell vor allem mit den Möglichkeiten von Serverless-Architektur. Zudem berät er unsere Kunden im Identity- und Accessmanagement.

Share on FacebookGoogle+Share on LinkedInTweet about this on TwitterShare on RedditDigg thisShare on StumbleUpon

Artikel von Jannik Hüls

Kommentare

  • September 20, 2016 von Thomas Darimont

    Hallo Jannik,

    vielen Dank für den interessanten Artikel!

    Ich glaube das in dem Artikel ein paar Abbildungen durcheinander geraten sind.
    Beispielsweise ist aktuell Abbildung 3 = Abbildung 2 ist und Abbildung 4 (mit dem OpenID Connect Flow) fehlt.
    Was aktuell Abbildung „4“ ist sollte wohl Abbildung 5 sein.
    Viele Grüße,
    Thomas

    • Jannik Hüls

      September 20, 2016 von Jannik Hüls

      Hi Thomas,

      vielen Dank für dein Feedback! Bei der Referenz auf die einzelnen Abbildung ist wirklich an einer Stelle etwas durcheinander geraten. Das habe ich nun korrigiert.

      Viele Grüße
      Jannik

Kommentieren

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *