Vor einiger Zeit haben wir Extras for Spring Security (XDEV SSE) veröffentlicht, um die Absicherung unserer Anwendungen zu vereinfachen.

Dieser Beitrag gibt einen Einblick in den Code und stellt einige Features vor, die auch für dich interessant sein könnten.

Übersicht

XDEV SSE bietet verschiedene Module, die es einfacher und sicherer machen, verschiedene Sicherheitslösungen in Spring-Anwendungen zu erstellen/verwalten, insbesondere in verteilten Systemen.
Es fügt Funktionen hinzu wie die Erinnerung an den letzten Identitätsanbieter des Benutzers, automatische Abmeldeprüfungen, verbesserte OAuth2/OIDC-Verwaltung, vereinfachte Frontend-Integration und das Wiederherstellen von bestehenden Anmeldungen nach einem Server-Neustart.
Außerdem sichert es Systemendpunkte, vermeidet unnötige Sessions und verfügt über integrierte Metriken.

Fast alles kann durch eine benutzerdefinierte Implementierung überschrieben oder bei Bedarf deaktiviert werden.

OAuth2/OIDC

Zugehörige Moduldokumentation: oauth2-oidc

Die meisten Anwendungen verwenden OAuth2 mit OpenID Connect (OIDC) als Aufsatz für die Authentifizierung.

Die Standardimplementierung von Spring Boot ist recht gut, aber es fehlen einige Funktionen:

Nach der initialen Anmeldung wird nie überprüft, ob diese noch gültig ist

Dies ist problematisch, wenn z.B. ein Mitarbeiter das Unternehmen verlässt und er immer noch auf die Anwendung zugreifen kann, was ein typischer Anwendungsfall für unsere Anwendungen ist.

Wie kann dies behoben werden?

Nun, OIDC bietet eine Funktion namens Back-Channel logout.

Die Standardlösung von Spring Boot ist ganz ok, allerdings gibt es ein paar Probleme:

  • Die Reaktion auf eine Back-Channel logout Anforderung muss manuell implementiert werden, was bei verteilten Systemen (Cluster) komplex sein kann.
  • Es muss sichergestellt werden, dass die “gepushte” Abmeldeanforderung immer das Zielsystem erreichen kann.
    • Auch das kann bei der Verwendungen von verteilten Systemen schwierig sein

Es gibt jedoch eine einfachere Lösung: Eine erneute Überprüfung, ob der Benutzer noch Zugriff auf den Identitätsanbieter hat.

XDEV SSE macht sich genau dies zunutze, indem es regelmäßig überprüft, ob der Benutzer noch Zugang hat.

Standardmäßig wird die Lebensdauer des OIDC accessToken verwendet, wodurch es auch möglich ist, dieses Verhalten für den Identitätsanbieter zu definieren.

Hier finden Sie einen vollständigen Funktionsvergleich:

Feature BackChannel-basierte Abmeldung AccessToken-Revalidierung mit XDEV SSE
Implementierung Manual implementation required XDEV SSE stellt vordefinierte Klassen zur Verfügung; minimaler Aufwand
Logout Logout-Anforderung durch den Identitätsanbieter Regelmäßig überprüft mit Hilfe des accessToken
Was passiert, wenn der Identitätsanbieter ausfällt? Kein zentraler Logout möglich Es gibt eine Übergangszeit (Standard: 3h), in welcher der Server nicht erreichbar sein darf. Aktive Anmeldungen werden während dieses Zeitraums nicht überprüft. Wenn die Frist abgelaufen ist und der Server immer noch nicht erreicht werden kann, werden alle Benutzer aus Sicherheitsgründen abgemeldet.

Es ist auch möglich beide Mechanismen zu kombinieren um das Beste aus beiden Welten zu nutzen.

Wie kann man dem Frontend mitteilen, dass der Benutzer abgemeldet ist?

Wir verwenden unsere Anwendungen in der Regel mit einem UI-Framework/Frontend, z.B. Vaadin.

Wir müssen diesem Framework irgendwie mitteilen, dass der Benutzer abgemeldet wurde.

Dafür stellt XDEV SSE einen ReloadCommunicator zur Verfügung, der verwendet werden kann, um dem Frontend mitzuteilen, dass eine bestimmte Aktion erforderlich ist.

Die Implementierung für Vaadin wird mit dem vaadin Modul bereitgestellt.

Automatische Neuwahl des Anbieters, der bei der letzten Anmeldung verwendet wurde

Angenommen ein Benutzer wird abgemeldet, weil seine Sitzung aufgrund von Inaktivität abgelaufen ist.

Was passiert, wenn man nur einen Identitätsanbieter in Spring Boot hat? Kein Problem: Der Benutzer wird automatisch zu diesem Provider umgeleitet.

Was aber, wenn man mindestens 2 Identitätsanbieter hat? Nun wird der Benutzer auf die Auswahl der Identitätsanbieter weitergeleitet und muss seinen Identitätsanbieter erneut auswählen. Die Liste kann lang sein und es ist mindestens ein zusätzlicher Klick erforderlich, so dass das für den Benutzer ziemlich lästig sein kann.

Aber wie wäre es, sie direkt zu ihrem letzten Anbieter umzuleiten? Genau das ist in der XDEV SSE mit ein paar Zeilen Code möglich.

Sichere Verwaltung der OIDC-Authentifizierung in einem verteilten System

Zugehörige Moduldokumentation: oauth2-oidc-remember-me

Wenn ein Client/Benutzer versucht, zu einer anderen Instanz der Webanwendung zu wechseln, z.B.

  • nachdem der Server neu gestartet wurde
  • nachdem er auf eine anderen Instanz im Clusters umgeleitet wurde

erkennt es die Sitzung und damit auch alle Authentifizierungsdaten nicht mehr an.

Niemand will, dass sich die Benutzer jedes Mal neu anmelden müssen, wenn ein neues Deployment ausgerollt wird oder eine neue Instanz im Cluster gestartet wird. Andernfalls werden diese sich ihr Kennwort auf einen Zettel schreiben und ihn unter den Monitor kleben, weil sie es so oft eingeben müssen.

Wie kann diese Situation also verbessert werden, so dass ein sicheres und bequemes Einloggen möglich ist?

Zu den vorhandenen Optionen gehören:

  • Speichern der Sitzung
  • Verwenden von Remember-Me Authentifizierung

Aber alle diese Optionen haben Nachteile, wie in der Dokumentation beschrieben.

XDEV SSE bietet die folgende Lösung an, die die meisten dieser Probleme behebt:

Die wichtigsten Erkenntnisse hier sind:

  • Wenn die persistenten Daten/das Backend gehackt werden sollte, sind die Daten für den Angreifer nutzlos:
    • Die Daten sind auf dem Client gespeichert, auf den der Angreifer nicht ohne weiteres zugreifen kann
    • Ein Angreifer muss beides bekommen: Den Server-Verschlüsselungsschlüssel (auf dem Server gespeichert) und die Client-Verschlüsselungsschlüssel (in der Datenbank gespeichert)
    • Die Verschlüsselungsschlüssel können leicht rotiert werden
  • Wenn die Daten vom Browser/Frontend gestohlen werden, sind sie für einen Angreifer nicht lesbar, da er die Verschlüsselungsschlüssel vom Backend benötigt
  • Die meiste Logik nach der Deserialisierung ist nicht erforderlich.
    Eine Revalidierung ist nur erforderlich, wenn der Client für längere Zeit nicht gesehen wurde.

Wenn man sich dafür interessiert, wie die Verschlüsselung und Speicherung funktioniert, kann man sich die Module crypto-symmetric und client-storage genauer ansehen.

Absicherung von Spring Boot Actuator

Zugehörige Moduldokumentation: web-sidecar-actuator

Spring Boot actuator erlaubt Management-Operationen via REST-Endpunkte über HTTP.

Es hat zu viele Vorfälle gegeben, bei denen jemand diese Endpunkte versehentlich öffentlich ins Internet gestellt hat, zum Beispiel:

Der web-sidecar-actuator sichert diese Endpunkte mittels explititer Authentifizierung ab. Dies erlaubt auch mehrere Benutzer in Kombination mit mehreren Endpunkten, so dass z.B. das Monitoring nur Zugriff auf den Endpunkt prometheus hat und keine Heapdumps ausführen darf.

Es stellt auch sicher, dass alle Anfragen, die nicht von actuator behandelt werden aber an actuator Pfade übergeben werden, nicht weiter verarbeitet werden. Dies ist hilfreich, wenn man ein benutzerdefiniertes Servlet (wie Vaadin) hat, welches diese Pfade nicht standardmäßig ignoriert.


Andernfalls könnte dies zu einer beschädigten Antwort führen, bei der eine Mischung aus der Actuator-Antwort „Authentifizierung fehlgeschlagen“ und der eigentlichen App-Antwort vorhanden ist.

Bereitstellung statischer Ressourcen

Zugehörige Moduldokumentation: web-sidecar-common

XDEV SSE bietet einen Mechanismus zur Registrierung öffentlich verfügbarer zustandsloser Ressourcen, wie statische Dateien. Dadurch wird verhindert, dass Sitzungen erstellt werden, wo sie nicht benötigt werden, zum Beispiel für robots.txt.

Integration mit Vaadin

Zugehörige Moduldokumentation: vaadin

Die Standard-WebSecurity-Implementierung von Vaadin wurde in mehreren Aspekten verbessert und um die bereits erwähnten Möglichkeiten von SSE erweitert:

  • gewährt Spring Security volle Zugriffskontrolle, bevor Anfragen von Vaadin verarbeitet werden
  • es werde nur dann (Vaadin-)Sitzungen erstellen, wenn sie wirklich benötigt werden, da die ziemlich schwergewichtig sind (Vaadin speichert den Zustand der Benutzeroberfläche in diesen Sitzungen)
  • verbessert die Anpassungsmöglichkeiten
  • enthält eine vordefinierte Content Security Policy für Vaadin
  • behandelt CSRF-Anfragen, die nicht von Vaadin verarbeitet werden sollen
  • erzwingt ein Neuladen der Seite (bei XHR-Anfragen), wenn die Authentifizierung abläuft

Metriken

Die meisten Module bieten zusätzliche Metriken, die zur Überwachung des Systems und zur Eingrenzung von Problemen genutzt werden können, z.B. Informationen darüber, wie viele Anfragen aufgrund fehlender Authentifizierung abgelehnt wurden.

Die Standardimplementierung liefert die Metriken an Spring Boot Actuator, aber man kann auch eine eigene benutzerdefinierte Implementierung nutzen.

Eine beispielhafte Darstellung mit Grafana könnte wie folgt aussehen:


Und das ist im Grunde alles.

XDEV SSE ist als OpenSource-Software auf GitHub einsehbar.
Wenn Ihnen der Artikel gefallen hat, können Sie dem Repository gerne einen Stern ⭐ geben.