Tomcat XCS – Cross context sessions

Einleitung
Das mein campus Projekt fasst mehrere eigenständige Webapplikationen unter einer Plattform zusammen. Oft werden die einzelnen Anwendungen sogar von unterschiedlichen Personen eigenständig entwickelt oder kommen von externen Entwicklern. Daher ist es wichtig, die Verschränkung der Anwendungen so gering wie möglich zu halten und so den Grad der nötigen Koordination unter den Entwicklern zu minimieren.
Das fördert die schnelle Entwicklung und erleichtert später die Wartbarkeit des Gesamtsystems.

Problematik
Wie bereits angedeutet sind in der mein campus Plattform verschiedene entkoppelte Webapplikationen vereint. Der Benutzer wird nach der Anmeldung in mein campus automatisch gegen die für ihn relevanten Anwendungen authentifiziert und kann transparent zwischen ihnen wechseln.
Bei dieser Technik verwaltet allerdings jede intergrierte Anwendung ihre eigenen Session, mit eigenem Ablaufzeitpunkt. Diese Ablaufzeit wird nur zurückgesetzt, wenn ein Zugriff auf die entsprechende Anwendung erfolgt.
Bewegt sich ein Nutzer allerdings gerade in einem anderen Teil/in anderen Anwendung von mein campus, so passiert kein Session-Update und die Session läuft aus. Bei erneutem Zugriff auf die Webapplikation mit abgelaufener Session hat der Nutzer die gespeicherten Session-Daten verloren.
Außerdem muss an diesem Punkt eine Strategie für die erneute Authentifizierung des Nutzers implementiert werden. Im schlimmsten Fall muss sich der Nutzer neu anmelden. Da sich die gesamte mein campus Plattform dem Benutzer als eine Anwendung präsentiert, ist dieses Verhalten für den Benutzer jedoch nicht nachzuvollziehen und muss verhindert werden – genau hier kommt das Tomcat XCS (Cross Context Session) ins Spiel, das für den Zweck der applikationsübergreifenden Session-Verwaltung innerhalb des Tomcat Servlet Containers bei CIT2 entwickelt wurde.

Funktionen
TouchSessionValve
Primäre Aufgabe des Tomcat XCS Moduls ist es, den Zeitpunkt des letzten Zugriffs auf Sessions mehrerer Webapplikationen synchron zu halten.
Die WebApps werden dazu in einem Verbund zusammengefasst und die Zugriffe auf diesen Verbund durch ein Tomcat Valve überwacht. Die Sessions aller WebApps können so dem zugreifenden User zugeordnet und gespeichert werden. Egal in welcher Applikation sich der User gerade bewegt werden im Hintergrund jeweils alle gespeicherten Sessions des Users einmal „angefasst“, um die AccessTime zu aktualisieren.

UsertrackValve
Um einen User beim Wechsel zwischen den überwachten Applikationen identifizieren zu können muss ihm eine eindeutige ID zugewiesen werden, welche er auch beim Wechsel zwischen den WebApps behällt. So kann der User auf seinem Weg zwischen den WebApps verfolgt werden und die korrekte Zuordnung der Sessions ist gewährleistet.

Cookies anyone?
Das XCS Modul nutzt normalerweise Cookies, um seine Arbeit im Hintergrund zu verrichten. Dies betrifft vor allem das UsertrackValve.
Clients, die keine Cookies unterstützen, werden jedoch automatisch erkannt und behandelt. Hierbei wird die UserId als GET Parameter URL Parameter ähnlich dem ;jsessionid= Parameter in die URL eingefügt. Das XCS Modul nutzt zur Einbettung des Parameters die aus der Servlet Spezifikation bekannte Methode HttpServletRequest.encodeURL() welche von modernen WebFrameworks ohnehin standardmäßig verwendet wird.

RMI Schnittstelle
Um Tomcat-interne Funktionen von der Kommandozeile nutzen zu können, stellt das XCS Modul einen RMI Server zur Verfügung. Dieser akzeptiert aus Sicherheitsgründen standardmäßig nur Verbindungen von localhost und muss explizit durch einen Konfigurationseintrag aktiviert werden.
Momentan existiert eine Beispielimplementierung, um einige statistische Informationen des XCS Moduls von der Kommandozeile abzufragen.
Die Schnittstelle ist jedoch sehr generisch und kann dazu genutzt werden, beliebige Tomcat-interne Methoden auch von der Kommandozeile -sogar über das Netzwerk- verfügbar zu machen.

Bewertung
Bei der Implementierung wurde sehr viel Zeit in die ordnungsgemäße Synchronisation der Datenstrukturen investiert, da Tomcat selbstversändlich von Haus aus mit mehreren parallelen Threads arbeitet. Neben der fehlerfreien Funktion war auch Performance einer der Schwerpunkte bei der Implementierung.

Ein Vergleichstest mit JMeter zeigt die Unterschiede zwischen einem Tomcat mit und ohne XCS:

JMeter mit 10 parallelen Threads a 20 Wiederholungen, Logging für XCS auf Level INFO

Das Ergebnis ist sicher nur eine grobe Hausnummer (anständige Tests sind aufwendig), lässt aber zumindest erahnen, dass kein besonders großer Einbruch unter Last zu erwarten ist.

Abgrenzung
Das Tomcat XCS Modul hat nichts mit folgendem Mechanismus zu tun!

Tomcat Docs
crossContext
Set to true if you want calls within this application to ServletContext.getContext() to successfully return a request dispatcher for other web applications running on this virtual host. Set to false (the default) in security conscious environments, to make getContext() always return null.

http://tomcat.apache.org/tomcat-5.5-doc/config/context.html#Common_Attributes

Dies ermöglicht es einer Webapp auf den ServletContext des übergeordneten Containers und damit auch auf die Session einer anderen Webapp zuzugreifen – was aus Sicherheitsgründen und zur Reduzierung von Abhängigkeiten zwischen eigentlich getrennten Webapps unbedingt vermieden werden sollte.

Im Gegensatz dazu arbeitet das Tomcat XCS Modul völlig transparent im Hintergrund und erfordert keinerlei Anpassungen oder Aufweichung der Context-Trennung der verwalteten Webapps.

Ausblick

Signierte userIds
Eine sicherheitsrelevante (aber nicht kritische!) Erweiterung ist die Verwendung von signierten UserIds. Auf diese Weise könnte das UsertrackValve Ids, die es nicht selbst erzeugt hat, erkennen und durch eine eigene ersetzen. Ist die mitgelieferte SessionId bereits im TouchSessionValve registriert, ist dieser Vorgang sogar vollkommen ohne Seiteneffekte für den Benutzer durchführbar.
Ohne dieses Feature könnten Benutzer die UserId verändern bevor sie an den Server gesendet wird und sich so eine eigene Id geben. Das ist im Prinzip kein Problem, allerdings etwas unschön und deshalb nicht gewünscht.

DataStore
Zum Datenaustausch zwischen mehreren WebApps könnte ein DataStore Modul hinzugefügt werden.

WebAuthentication
Eine Schnittstelle für die programmatisches Authentifizierung am Tomcat Container (siehe auch http://community.jboss.org/wiki/WebAuthentication).
Dadurch könnten Tomcat-interne Mechanismen, wie das SingleSignOnValve genutzt werden, um einen BackgroundLogin für mehrere WebApps bereitzustellen.

Diese Lösung ist im Gegensatz zu SSO lokal begrenzt. Der Konfigurations- und Anpassungsaufwand ist also gemessen an WebSSO Systemen sehr gering:

  • keine SSO Infrastruktur nötig (SP/IdP)
  • keine Redirects
  • keine SSO Auth Plugins für Webapps

Ein authentifizierter Benutzer samt Rollen kann einfach durch Aufruf der spezifizierten Servlet Methoden getRemoteUser() bzw. getUserPrincipal() oder isUserInRole() ermittelt werden.

Tests/Portierung zum JBoss
Bislang wurden noch keine Tests im JBoss durchgeführt.

generische Sessions
In der aktuellen Version setzt das XCS Modul auf die Servlet Spezifikation und kann nur J2EE konforme Sessions mit dem Parameternamen JSESSIONID verwalten.
Eine Erweiterung auf generische Sessions mit beliebigem Parameternamen würde auch Anwendungen mit mehreren Sessions unterstützen können. Allerdings wird die Session-Verwaltung in so gut wie allen Fällen ohnehin von einem J2EE konformen Framework übernommen und entspricht somit der Servlet Spezifikation.

Momentan wird das Tomcat XCS Modul für eine Veröffentlichung unter einer Open-Source-Lizenz aufgearbeitet. In Zuge dessen erfolgt auch die Dokumentation über Einsatz und Installation des Moduls – denn die applikationsübergreifende Session-Verwaltung und -Synchronisierung mittels des Tomcat Servlet Container ist  sicherlich auch für andere Portale als nur die Online-Serviceplattform mein campus interessant.