Warum können WARs keine Sitzungsinformationen teilen?

11

Ich habe mehrere Entwickler gesehen, die nach einer Lösung für dieses Problem gesucht haben: Zugriff auf Sitzungsinformationen aus einem anderen WAR (auch wenn sie sich in derselben EAR befinden) - hier einige Beispiele: Gibt es eine Möglichkeit, den Sitzungsstatus zwischen verschiedenen Anwendungen in Tomcat zu teilen? , Zugriffssitzung einer anderen Webanwendung , verschiedene WAR-Dateien, freigegebene Ressourcen , Tomcat: Wie kann ich Daten zwischen zwei Anwendungen austauschen? , Was macht das Attribut crossContext in Tomcat? Aktiviert es die Sitzungsfreigabe? und so weiter...

Nach allem, was ich gesucht habe, gibt es je nach Container einige spezifische Lösungen, aber es widerspricht irgendwie der Spezifikation . Ich habe auch die Java EE-Spezifikation durchgesehen, ohne Glück, eine Antwort zu finden.

Einige Entwickler sprechen über die Kopplung zwischen Webanwendungen, aber ich bin eher anderer Meinung. Was ist der Grund, warum man WARs innerhalb derselben EAR halten würde, wenn man nicht koppelt? Auf EJBs kann beispielsweise lokal zugegriffen werden (auch wenn sie sich in einer anderen EJB-JAR innerhalb derselben EAR befinden).

Insbesondere übernimmt eine meiner WARs die Authentifizierung und Autorisierung, und ich möchte diese Informationen mit anderen WARs (in derselben EAR) teilen. Ich habe es zuvor geschafft, ähnliche Probleme zu umgehen, indem ich WARs als JARs verpackt und in ein einzelnes WAR-Projekt (WEB-INF / lib) eingefügt habe. Diese Lösung gefällt mir jedoch nicht (sie erfordert einen enormen Aufwand bei der Benennung von Servlets usw.).

Und keine Lösung hat die erste (und wichtigste) Frage beantwortet: Warum können WARs keine Sitzungsinformationen austauschen?

rvcoutinho
quelle
1
Ich bin mir nicht sicher, warum dies abgelehnt wurde, außer dass es besser zu SO passt.
NateDSaint
3
"Gemäß der Servlet 2.3-API-Spezifikation unterstützt der Sitzungsmanager das Sitzungs-Scoping nur nach Webmodul. Nur Servlets im selben Webmodul können auf die Daten zugreifen, die einer bestimmten Sitzung zugeordnet sind." Dies ist in HttpSession wieder zu sehen - "Sitzungsinformationen gelten nur für die aktuelle Webanwendung (ServletContext), sodass in einem Kontext gespeicherte Informationen in einem anderen nicht direkt sichtbar sind." - Dies widerspricht der Spezifikation.
(Besser, aktueller Link für HttpSession )
@ MichaelT, danke. Aber es antwortet immer noch nicht warum.
rvcoutinho
@NateDSaint Obwohl sich die Frage auf bestimmte Technologien bezieht, glaubte ich, dass es sich eher um eine konzeptionelle Frage handelt. Dann habe ich mich für Programmierer entschieden.
rvcoutinho

Antworten:

7

Behandeln Sie eine EAR wie eine pseudo-virtuelle Maschine

Eine EAR ist einfach eine Sammlung von WAR-Dateien, die gemeinsame Konfigurationen und Bibliotheken verwenden, normalerweise von JARs. Auf diese Weise kann eine Sammlung von voneinander abhängigen Diensten einfacher in einem Anwendungscontainer verwaltet werden. Daher können Sie sich eine EAR als einfache Form einer virtuellen Maschine vorstellen, sobald sie in ihrem Container bereitgestellt wird.

Ebenso wie ein Prozess auf einer virtuellen Maschine keinen anderen beeinflussen kann, gilt dies auch für eine EAR. Alle WARs sind isoliert, um ihren internen Zustand zu schützen.

Skalieren der Authentifizierung

Im Allgemeinen müssen Webanwendungen zustandslos sein, um eine gute Skalierung zu gewährleisten. Viele Informationen in der Sitzung zu haben, ist ein Anti-Muster, das dies verhindert. Dies führt zu einem Konflikt zwischen der Statuslosigkeit von HTTP und der Notwendigkeit, eine schnelle, angepasste Benutzererfahrung aufrechtzuerhalten. Die Authentifizierung ist ein klassischer Anwendungsfall und wird häufig in Chat-APIs verwendet, für die viele authentifizierte Anforderungen erforderlich sind, um Endbenutzerfunktionen bereitzustellen.

Single Sign On und Single Sign Off erfordern eine sorgfältige Signalisierung, um korrekt zu funktionieren (teilweise Abmeldung berücksichtigen), insbesondere wenn eine horizontale Skalierung vorhanden ist. Das einfache Teilen des Sitzungsstatus ist fast nie eine gute Lösung. Ein besserer Ansatz besteht darin, einen einzigen Bezugspunkt für die Benutzerinformationen zu verwenden, auf die alle Knoten im Cluster Zugriff haben.

Wenn Sie sich auf den schnellen zwischengespeicherten Zugriff auf relevante Informationen konzentrieren, erhalten Sie weitaus skalierbarere Ergebnisse als bei einer komplexen, fragilen Lösung für die gemeinsame Nutzung von Sitzungen.

Gary Rowe
quelle
Danke, @GaryRowe. Dies ist die Antwort, nach der ich gesucht habe. Könnte das nicht der Entwickler entscheiden?
rvcoutinho
Eine andere Frage: Würden Sie denken, dass JBoss Cache eine gute Lösung sein könnte? Haben Sie von Apache Shiro (und seinem Sitzungsclustering) gehört? Was ist damit?
rvcoutinho
@rvcoutinho Entscheidet der Anwendungsentwickler, wie Prozesse im Linux-Kernel verwaltet werden? Es ist eine ähnliche Formulierung einer Frage - ja, Sie könnten es tun, aber es wird extrem schwierig und verursacht Ihnen wahrscheinlich mehr Schmerzen als der alternative Weg.
Gary Rowe
2
@rvcoutinho Ich habe Apache Shiro (auch bekannt als Apache Security) nicht verwendet, aber ich stelle mir vor, dass dies eine gute Lösung für das Problem der gemeinsamen Sicherheit wäre. Erwägen Sie auf jeden Fall die Integration in OpenID und OAuth2, anstatt Ihr eigenes Protokoll zu erstellen, um dasselbe zu erreichen. JBoss Cache wird nach eigenen Angaben in einer Sackgasse durch Infinispan ersetzt, was ziemlich komplex aussieht. Vielleicht möchten Sie einen Blick auf die Twelve-Factor App-Website werfen, um einen Einblick in eine einfachere, skalierbarere Lösung zu erhalten.
Gary Rowe
2

Ich denke, es fehlt etwas an Funktionalität in der JEE EAR-Spezifikation - die Möglichkeit, Websitzungen über mehrere innerhalb einer EAR gebundene Webarchive hinweg zu teilen.

App-Server wie Weblogic haben nicht standardmäßige Implementierungen für diese Funktionalität.

Martijn Verburg
quelle
Das war bisher meine Meinung. Ich habe versucht zu verstehen, warum die erwähnte Wahl getroffen wurde.
rvcoutinho
1

Nun, AFAIKS, es gibt keinen wirklichen Grund, warum Sie dies tun möchten. Ein WAR ist eine eigenständige Webanwendung mit eigenen (webanwendungsspezifischen) Bereichen (wie dem Sitzungsbereich). Wenn Sie Funktionen (Java-Code, JSP-Seiten, CSS-Dateien) gemeinsam nutzen müssen, haben Sie zwischen mehreren WARs die weitaus sinnvollere Möglichkeit, sie als JAR-Dateien zu verpacken und auf Ihrem Anwendungsserver bereitzustellen. Ein WAR-Paket ist eine komplexere Verpackungslösung, die etwas anderes als einfachen "allgemeinen Code / Funktionalität" enthält. Die JAR ist ein einfacheres Format UND dient zum Packen und Freigeben von Code und Funktionen. Warum sollten Sie eine komplexere und nicht speziell für diese Verpackung entwickelte Verpackung verwenden, um etwas gemeinsam zu nutzen, wenn Sie bereits ein einfacheres und für dieses Paket geeigneteres Paketformat zur Verfügung haben?

Shivan Drache
quelle
Ich stimme mit Ihnen ein. Aber nur, wenn es nur um allgemeine Ressourcen geht. Für eine einmalige Anmeldeanwendung müsste ich jedoch sitzungsspezifische Informationen (über den angemeldeten Benutzer) freigeben. Und ich sehe keinen Grund, warum dies gegen die Spezifikation wäre.
rvcoutinho
2
Da der Sitzungsbereich nicht für die gemeinsame Nutzung aktueller Benutzerdaten zwischen verschiedenen Anwendungen vorgesehen ist. Und weil SSO mehr beinhaltet als das Überprüfen von Sitzungsbereichsattributen. Sie können Code außerhalb Ihres Krieges erstellen und verpacken (und der nicht von Ihrem Krieg abhängt, sondern den Krieg davon abhängt), der auf Sitzungsbereichsattribute zugreift, wenn Sie möchten (wie ein Filter), aber meiner Meinung nach die bessere Lösung wäre eine separate Fassadenanwendung oder Serverkonfiguration zu haben, die sich mit der Authentifizierung befasst und Zugriff auf andere (vom Krieg bereitgestellte) Anwendungen gewährt.
Shivan Dragon
Ich würde dir wieder zustimmen. Die JavaEE-Spezifikation (unter Verwendung von JAAS) enthält die Benutzerinformationen jedoch als Teil der HttpSession, was diesem Ansatz entgegensteht. Einer der Gründe, warum ich überlegt habe, stattdessen Shiro zu verwenden (es wird eine orthogonale Sitzung beibehalten).
rvcoutinho
Trotzdem danke für die Antwort. Ich habe noch keine endgültige Antwort auf meine Frage, aber alles, was Sie gesagt haben, ist relevant. +1
rvcoutinho
@rvcoutinho gut, das ist meine Meinung zu diesem Thema, sorry, es war nicht hilfreicher für dich.
Shivan Dragon
0

Ich denke, dies wurde absichtlich gemacht, um zu vermeiden, dass verschiedene Web-Apps versehentlich die Sitzungsinformationen der anderen überschreiben. In Ihrem Fall mag dies nützlich sein, aber im Allgemeinen möchten Sie nicht, dass Benutzer die App zum Absturz bringen oder ihre Berechtigungen erweitern, nur weil sie zwei Web-Apps gleichzeitig verwenden. Es ist nicht gerade schwierig, Informationen explizit zwischen Web-Apps auszutauschen. Erstellen Sie einfach eine Klasse mit einer statischen HashMap, verwenden Sie GUIDs als Schlüssel und übertragen Sie sie als Teil des URL- oder HTTP-Parameters.

user281377
quelle
Vielen Dank. Eigentlich habe ich nicht über das Teilen der gesamten Sitzung zwischen jeder Anwendung gesprochen, sondern über bestimmte Sitzungsinformationen (als Benutzerinformationen) bei Bedarf. Vielleicht war ich nicht klar. Irgendwelche Vorschläge, um es klarer zu machen?
rvcoutinho