Zugriff in Tomcat-Realm auf Session

MartinLeim

Grünschnabel
Wir arbeiten gerade an einem 3-Tier-System, bei dem eine in Tomcat gestartete Struts-Anwendung auf einen weiteren Server zugreift.

Die Seiten sollen durch ein Security-Constraint geschützt werden. Dort soll mittels eines entsprechenden Realms ein Login beim Server durchgeführt werden. Der Server bestätigt diesen Login gegebenfalls mit einer Session-ID, die für weitere Kommandos an den Server mitgeschickt werden muss.

Und genau das ist der Knackpunkt: Für die Authentifikation könnte ein selbst geschriebenes Realm bzw. ein JAAS-LoginModule verwendet werden. Dort kann problemlos die Prüfung von name und Passwort sowie die Rollenzuteilung geschehen. Aber ich hab dort keinen Zugriff auf die HTTP-Session, in der die Session-ID des obersten Servers gespeichert werden müsste.


Hat da jemand eine Idee, wie man vorgehen könnte?


Besten Dank,
Martin
 
Hallo!

Ich denke nicht, dass SSO damit was zu tun hat, da nur eine Webanwendung daran beteiligt ist.

Ich erkläre das Problem etwas ausführlicher:

Ich hab 3 Schichten (4, wenn man die Datenbank mitzählt): Erste Schicht ist der Webclient. Dieser kommuniziert mit einer in Tomcat laufenden Webanwendung (nennen wir sie S1). Diese wiederum kommuniziert mit einem weiteren Server (nennen wir ihn S2), der auf die Datenbank zugreift.

S2 verwaltet die Benutzeraccounts, d.h. ein Login wird an S2 durchgeführt. Zur Identifikation von Benutzern wird eine Session-ID erzeugt, die bei jeder Anfrage an S2 mitgeleifert werden muss.
Die Anwendung in S1 ist natürlich auch passwortgeschützt, sie stellt ja gerade eine Kapselung eines Teils der Funktionalität von S2 dar. Und um die Authentifizierung der Web-Anwendung nicht selbst programmieren zu müssen, dachte ich an Security-Constraints mit einem Realm. Dieser Realm muss dann Benutzername und Passwort an den Server weiterreichen. Ist der Login erfolgreich, muss die Session-ID des Servers erhalten bleiben, damit weitere Anfragen dieses Benutzers sie verwenden können. Dafür wäre es praktisch, wenn ich Zugriff auf die HTTP-Session hätte, was aber so ohne weiteres nicht geht (zumindest wüsste ich nicht, wie).

Ich kann mir nicht vorstellen, dass meine Problemstellung so selten vorkommt, da eine Webanwendung doch durchaus desöfteren als Middleware eingesetzt wird, oder? Gibt es da keine Musterlösungen oder hab ich nur einen Denkfehler?

Ich hoffe, das Problem ist jetzt verstanden.
 
Hallo!

Ich denke nicht, dass SSO damit was zu tun hat, da nur eine Webanwendung daran beteiligt ist.

Wir arbeiten gerade an einem 3-Tier-System, bei dem eine in Tomcat gestartete Struts-Anwendung auf einen weiteren Server zugreift.

Ich hab 3 Schichten (4, wenn man die Datenbank mitzählt): Erste Schicht ist der Webclient. Dieser kommuniziert mit einer in Tomcat laufenden Webanwendung (nennen wir sie S1). Diese wiederum kommuniziert mit einem weiteren Server (nennen wir ihn S2), der auf die Datenbank zugreift.
Web Client = Web App in S1, Weitere (Web?) App in S2 .. also zwei App.

S2 verwaltet die Benutzeraccounts, d.h. ein Login wird an S2 durchgeführt. Zur Identifikation von Benutzern wird eine Session-ID erzeugt, die bei jeder Anfrage an S2 mitgeleifert werden muss.
Die Anwendung in S1 ist natürlich auch passwortgeschützt, sie stellt ja gerade eine Kapselung eines Teils der Funktionalität von S2 dar.

Na ja, für mich klingt das immernoch nach einem Single Sign On Szenario, denn genau das wollt ihr da machen. Eine zentrale Instanz (S2) übernimmt die Aufgaben der Authentifikation und Authorisierung und bietet die entsprechenden Dienste anderen Anwendungen (wie z.Bsp. S1) an.

Wie gesagt genau für so ein Szenario sind Frameworks wie JOSSO gedacht.

Die Anwendung in S1 ist natürlich auch passwortgeschützt, sie stellt ja gerade eine Kapselung eines Teils der Funktionalität von S2 dar.
Authentifiziert sich S1 auch gegen S2, sprich verwendet S1 user Credentials aus S2 oder gibt es dort wieder eigene?

Und um die Authentifizierung der Web-Anwendung nicht selbst programmieren zu müssen, dachte ich an Security-Constraints mit einem Realm. Dieser Realm muss dann Benutzername und Passwort an den Server weiterreichen. Ist der Login erfolgreich, muss die Session-ID des Servers erhalten bleiben, damit weitere Anfragen dieses Benutzers sie verwenden können. Dafür wäre es praktisch, wenn ich Zugriff auf die HTTP-Session hätte, was aber so ohne weiteres nicht geht (zumindest wüsste ich nicht, wie).
Wieso existiert vor dem Anmelden schon eine Session?
Ich würde an deiner Stelle, die Login Seite so gestalten, dass erst nach einem erfolgreichen Login eine Session erzeugt wird.
Siehe:
http://www.tutorials.de/tutorials230390.html&highlight=jsp+session

Gruß Tom
 
Hm, auch wenn das ein SSO-Szenario ist, ich sehe nicht, wie mir bspw. JOSSO da weiterhelfen kann. Ich hab mir das mal kurz angekuckt und da ist von irgendwelchen Rollen und Benutzern in Datenbanken die Rede.

Die Server-Anwendung S2 ist keine Web-Anwendung, sondern eine Stand-Alone-Anwendung. Die Web-Anwendung S1 kommuniziert mit dieser mittels RMI.

Pseudo-Code-mäßig würde die Authentifizierung seitens der Webanwendung S1 so aussehen:

Code:
server = Connection.getConnection; //Baue Verbindung zu Server auf
String sid = server.login(name, password);

if (sid == null) {
  // nicht eingeloggt
} else {
  // eingeloggt (Rolle zuweisen, diese wird mittels einer weiteren Server-Anfrage ermittlt)
  // * Session-ID irgendwo speichern, wo sie aus der Anwendung verwendet werden kann
}


Das wäre also schon alles. Wenn das Problem nicht wäre, dass ich nicht weiß, ob und wie die mit * markierte Aktion machbar ist...

Ich denke nicht, dass ich ein weiteres Framework kennenlernen muss, um so eine doch relativ einfache Aufgabe zu lösen.
Gibt es nicht einen Hack, um das zu ermöglichen? Da die Anwendung ohnehin nur in Tomcat lauffähig sein soll, ist Konformität mit J2EE-Standards weitgehend egal.


Gruß
Martin
 
Hallo!

Die Server-Anwendung S2 ist keine Web-Anwendung, sondern eine Stand-Alone-Anwendung. Die Web-Anwendung S1 kommuniziert mit dieser mittels RMI.
Woraus wird die RMI Anwendung denn aufgerufen?
Aus einem Servlet oder dem von dir erwähnten LoginModule...?

Das wäre also schon alles. Wenn das Problem nicht wäre, dass ich nicht weiß, ob und wie die mit * markierte Aktion machbar ist...
Wenn die Aktion innerhalb eines Servlets geschieht, würde ich diese "sid" in der HTTPSession ablegen.
Wie du in einem Servlet an die aktuelle HTTPSession heran kommst weist du ja?

Gruß Tom
 
Thomas Darimont hat gesagt.:
Woraus wird die RMI Anwendung denn aufgerufen?
Aus einem Servlet oder dem von dir erwähnten LoginModule...?

Aus beiden: Der Login aus dem LoginModule und die übrigen Aufrufe aus dem Servlet.




Aber ich denke, ich hab eine Lösung gefunden. Zwar nicht so ganz sauber, aber wenn sie funktioniert, reicht das aus.
Ich versuch sie mal zu implementieren, wenn es klappt, stell ich sie vor.

Danke
Martin
 
Hallo!

Okay. Statt mich mit umständlichen JAAS Modulen / Callbacks etc herumzuschlagen würde ich mir einfach sowas wie einen eigenen RMIRealm implementieren... einfach von org.apache.catalina.realm.RealmBase ableiten und dort die Authentifikation durchführen. Dann könnte man beispielsweise eine von java.security.Principal abgeleitete Benutzerinkarnation zurückgeben, die die entsprechende sid beinhaltet. So käme man auch immer vom jeweiligen User auf die passende sid.

Gruß Tom
 
Ja, sowas in der Art hatte ich vor.
Allerdings mittels JAAS, da ich den Aufwand der Implementation eines eigenen Realms nicht ganz abschätzen kann.
Der Benutzer-Principal erhält dann einfach die Session-ID als Name, auf diese Id hab ich dann in der Web-Anwendung Zugriff.

Theoretisch sollte das super funktionieren, auch wenn Tomcat mich gerade ärgert, indem er immer einen MemoryRealm für meinen Kontext verwendet, auch wenn ein JAASRealm oder sogar gar kein Realm angegeben ist!

Naja, das sollte aber zu lösen sein.


Vielen Dank auf jeden Fall mal!
 
Zurück