Wir hatten bei einem Kunden die Notwendigkeit, eine Webanwendung per Single-Sign-On, im weiteren Verlauf als SSO bezeichnet, abzusichern. Dabei werden die Daten für die Authentifizierung und Autorisierung benutzt, die der Benutzer schon bei der Anmeldung in der Windows-Domäne eingegeben hat. Hierbei kommuniziert der Webbrowser über einen speziellen Mechanismus (Kerberos) mit der Webanwendung und dem Active Directory, welches hier als Authentication-Service und Ticket Granting Service fungiert. Eine einfache Erläuterung des Mechanismus kann man hier erhalten .
Gibt’s da nicht was von Spring?
Nun hatten wir beim Kunden zudem die Anforderung, dass das SSO der Webanwendung sowohl im altbewährten Websphere Application Server als auch in einem Tomcat im Docker-Container funktionieren soll. Insbesondere hierin bestand die Herausforderung. Da es sich bei der Webanwendung im weitesten Sinne um eine Spring-Anwendung handelt, haben wir uns für die Spring-Lösung mit Spring-Security und Spring-Security-Kerberos entschieden. Dieses ließ sich leicht integrieren und durch die Nutzung von Profilen für Websphere und Tomcat auch leicht konfigurieren.
Konfiguration
Zunächst muss ein WebApplicationInitializer im Klassenpfad platziert werden, der mittels Servlet-3.0-Api automatisch geladen wird und die Spring-Security springSecurityFilterChain mit einer Reihe von HTTP-Servlet-Filtern registriert. Der dafür vorgesehene WebApplicationInitializer muss die Spring-Klasse AbstractSecurityWebApplicationInitializer erweitern, kann ansonsten aber leer sein. Dieser WebApplicationInitializer registriert allerdings nur die Referenzen auf die Servlet-Filter-Chain, daher müssen des Weiteren noch weitere Spring-Beans erzeugt werden. Mithilfe von Java-Config kann das leicht erfolgen. Hierzu wird im ApplicationContext der Anwendung eine Konfiguration abgelegt, die die Spring-Klasse WebSecurityConfigurerAdapter erweitert und mit @EnableWebSecurity annotiert wird. In dieser Konfigurationsklasse werden nun auch die Spring-Beans erzeugt, die für den Kerberos-Mechanismus nötig sind. Hierzu zählen insbesondere KerberosTicketValidator, KerberosServiceAuthenticationProvider, SpnegoAuthenticationProcessingFilter und SpnegoEntryPoint.
Ein Beispiel, wie die Konfiguration aussehen könnte:
Wie man sehen kann, ist diese Konfiguration abstrakt und muss noch implementiert werden. Dies wurde nun profilabhängig für den Websphere und den Tomcat implementiert, um die unterschiedlichen Systeme abzubilden. Dazu nun also zwei Konfigurationen.
Websphere-Konfiguration
Tomcat-Konfiguration
Vorbereitung des Key Distribution Center (KDC)
In dem Beispiel wird die Rolle des KDC vom Active Directory ausgefüllt. Wie man sieht, wurden in der Konfiguration sogenannt „Service-Principals“ und weitere Dateien referenziert, auf die ich im folgenden eingehe.
1. Service-Principal
Der Service-Principal, kurz SPN, bezeichnet den Namen eines Dienstes im der Netzwerk-Domäne mit Kerberos-Authentifizierung. Dieser besteht aus der Dienstklasse, einem Hostnamen und ggf. einem Port. In dem Beispiel gibt es für jeden Server, der die Webanwendung bereitstellt, einen SPN der Dienstklasse HTTP.
- HTTP/tomcat.codecentric.de
- HTTP/websphere.codecentric.de
Der Hostnamen muss dem entsprechen, wie die Anwendung vom Webbrowser aufgerufen wird. In dem Beispiel könnte es also die URL https://tomcat.provinzial.com:8080/beispiel sein. Diese beiden SPNs müssen im KDC nun registriert und einem Benutzer zugeordnet werden. Hierzu werden in einer Windows-Konsole (der PC muss in der Domäne angemeldet sein) die folgenden Befehle ausgeführt:
Mit diesem Befehl wird der SPN im erzeugt und dem Benutzer A_KERBEROS_USER zugeordnet.
2. kerberos.keytab
Diese Datei ist der Schlüssel, der zwischen der Webanwendung und dem KDC zur Authentifizierung benutzt wird.
Der Befehlt legt für den Benutzer A_KERBEROS_USER und sein Passwort A_SECRET_PASSWD die Keytab-Datei an, die jedoch nur für den SPN HTTP/tomcat.codecentric.de verwendet werden kann. Für den SPN HTTP/websphere.codecentric.de muss analog dazu eine weitere Keytab-Datei erzeugt werden.
3. krb5.ini
In dieser Datei wird Kerberos selbst konfiguriert. Hier wird zum Beispiel der KDC konfiguriert:
Diese Konfiguration ist stark von der Domänen-Konfiguration im Active Directory abhängig. Dies hier ist nur ein Beispiel.
Aufruf der Webanwendung
Nach dem Erstellen der notwendigen Dateien und dem Deployment der Webanwendungen mit der obigen Spring-Konfiguration wird beim Aufruf des URL https://tomcat.codecentric.de/beispiel der Kerberos-Mechanismus in Gang gesetzt. Zunächst prüft die Anwendung, ob der Aufrufer schon eingeloggt ist, wenn nicht, schreibt der SpnegoEntryPoint einen HTTP-Header (WWW-Authenticate=Negotiate) und gibt Status 401 zurück. Damit weiß der Webbrowser, dass er die Daten des Windows-Benutzers in einem neuen Request das Kerberos-Ticket im HTTP-Header mitsenden muss. Dieses Ticket liegt entweder schon im Ticket-Cache oder es muss noch beim KDC geholt werden.
Webspheres IBM Runtime Java
Die Spring-Bibliothek für Kerberos beinhaltet leider nur einen KerberosTicketValidator, der mit dem Oracle-JRE funktioniert und explizit nicht mit dem IBM-JRE. Speziell die Referenz auf die Implementierung des LoginModule ist bei der IBM-JRE eine andere. Einen weiteren Unterschied bildet die Implementierung der Kommunikation mit dem KDC.
Die IBM-Implementierung ist im Wesentlichen eine Kopie des SunJaasKerberosTicketValidator bis auf folgende Ausschnitte:
Die Implementierung der run()-Methode geht auf die Dokumentation von IBM zurück.
Möglichkeit des Aufrufs ohne SSO
Eine letzte Anforderung war die Schaffung der Möglichkeit, einen Login in die Webanwendung zu ermöglichen, ohne dass eine automatische Anmeldung per SSO erfolgt. Dies kann nützlich sein, wenn der Anwender sich nicht mit seinem eigenen Benutzer, sondern mit einem fremden anmelden möchte.
Die Idee hierzu war simpel. Es wurde ein Hostname im DNS eingetragen, der die Subdomäne nosso enthält und auf die gleiche IP zeigt wie der Hostname ohne nosso-Subdomäne. In dem Beispiel wäre die Webanwendung also auch über die URL https://tomcat.nosso.codecentric.de/beispiel erreichbar.
In der Webanwendung wurde dann in dem eigenen SpnegoEntryPoint eine Weiche implementiert. Der Ausschnitt der überschrieben Methode zeigt die Weiche.
Somit wird der Aufruf von https://tomcat.nosso.codecentric.de/beispiel keinen Kerberos-Mechanismus auslösen, sondern zu einem Redirect zu https://tomcat.nosso.codecentric.de/beispiel/login führen, wo der Anwender dann die gewünschten Benutzerdaten eingeben kann.
Fazit
Viel Experimentieren war notwendig, um diese Lösung zu erarbeiten. Ich hoffe, mit meiner Ausführung dazu beitragen zu können, dass künftig weniger experimentiert werden muss.
Weitere Artikel in diesem Themenbereich
Entdecke spannende weiterführende Themen und lass dich von der codecentric Welt inspirieren.
Blog-Autor*in
Thomas Bosch
IT Consultant
Du hast noch Fragen zu diesem Thema? Dann sprich mich einfach an.
Du hast noch Fragen zu diesem Thema? Dann sprich mich einfach an.