Pourquoi les WAR ne peuvent-ils pas partager les informations de session?

11

J'ai vu plusieurs développeurs à la recherche d'une solution à ce problème: accéder aux informations de session à partir d'un autre WAR (même à l'intérieur du même EAR) - voici quelques exemples: Comment partager l'état de session entre différentes applications dans tomcat? , Session d'accès d'une autre application web , différents fichiers WAR, ressources partagées , Tomcat: Comment partager des données entre deux applications? , Que fait l'attribut crossContext dans Tomcat? Est-ce que cela permet le partage de session? etc...

D'après toutes mes recherches, il existe des solutions spécifiques en fonction du conteneur, mais elles sont en quelque sorte « contraires aux spécifications ». J'ai également examiné la spécification Java EE sans aucune chance de trouver une réponse.

Certains développeurs parlent de couplage entre les applications Web, mais j'ai tendance à ne pas être d'accord. Quelle est la raison pour laquelle on garderait les WAR à l'intérieur du même EAR si ce n'est pas le couplage? Les EJB, par exemple, sont accessibles localement (même si à l'intérieur d'un autre JAR EJB dans le même EAR).

Plus précisément, l'un de mes WAR gère l'authentification et l'autorisation, et je voudrais partager ces informations avec d'autres WAR (dans le même EAR). J'ai réussi à contourner des problèmes similaires auparavant en empaquetant les fichiers WAR sous forme de fichiers JAR et en les plaçant dans un projet WAR unique (WEB-INF / lib). Pourtant, je n'aime pas cette solution (elle nécessite un énorme effort sur le nommage des servlets, etc.).

Et aucune solution n'a répondu à la première (et la plus importante) question: pourquoi les WAR ne peuvent-ils pas partager les informations de session?

rvcoutinho
la source
1
Je ne sais pas pourquoi cela a été rejeté, sinon cela pourrait être mieux adapté pour SO.
NateDSaint
3
"Conformément à la spécification de l'API servlet 2.3, le gestionnaire de sessions prend en charge la portée de session par module Web uniquement. Seules les servlets du même module Web peuvent accéder aux données associées à une session particulière." Cela peut être vu à nouveau dans HttpSession - "Les informations de session ne sont étendues qu'à l'application Web actuelle (ServletContext), donc les informations stockées dans un contexte ne seront pas directement visibles dans un autre." - Cela est contraire aux spécifications.
(mieux, lien actuel pour HttpSession )
@MichaelT, merci. Mais cela ne répond toujours pas pourquoi.
rvcoutinho
@NateDSaint Même si la question est liée à des technologies spécifiques, je pensais que c'était probablement une question conceptuelle. Ensuite, j'ai décidé pour les programmeurs.
rvcoutinho

Réponses:

7

Traitez un EAR comme une machine pseudo-virtuelle

Un fichier EAR est simplement une collection de fichiers WAR qui partagent une configuration et des bibliothèques communes, généralement à partir de fichiers JAR. Cela permet de gérer plus facilement un ensemble de services interdépendants dans un conteneur d'applications. Ainsi, vous pouvez considérer un EAR comme une simple forme de machine virtuelle une fois qu'il est déployé dans son conteneur.

De la même manière qu'un processus sur une machine virtuelle ne peut pas affecter un autre, il en va de même pour un EAR. Tous les WAR sont isolés pour protéger leur état interne.

Authentification évolutive

En général, les applications Web doivent être sans état pour bien évoluer. Avoir beaucoup d'informations dans la session est un anti-modèle qui empêche cela. Cela conduit à un conflit entre la nature sans état de HTTP et la nécessité de maintenir une expérience utilisateur rapide et personnalisée. L'authentification est un cas d'utilisation classique et est répandue dans les API bavardes qui nécessitent un grand nombre de demandes authentifiées pour offrir des fonctionnalités à l'utilisateur final.

La signature unique et la signature unique nécessitent une signalisation minutieuse pour fonctionner correctement (pensez à la signature partielle), en particulier lorsque la mise à l'échelle horizontale est en place. Le simple partage de l'état de session n'est presque jamais une bonne solution et une meilleure approche consiste à utiliser un point de référence unique pour les informations utilisateur auxquelles tous les nœuds du cluster ont accès.

Se concentrer sur un accès rapide en cache aux informations pertinentes produira des résultats beaucoup plus évolutifs que certaines solutions de partage de session complexes et fragiles.

Gary Rowe
la source
Merci, @GaryRowe. C'est la réponse que je cherchais. Quoi qu'il en soit, cela ne pourrait-il pas appartenir au développeur de décider?
rvcoutinho
Une autre question: pensez-vous que JBoss Cache pourrait être une bonne solution? Avez-vous entendu parler d'Apache Shiro (et de son regroupement de sessions)? Qu'en est-il?
rvcoutinho
@rvcoutinho Le développeur de l'application décide-t-il comment les processus sont gérés dans le noyau Linux? C'est un cadrage similaire d'une question - oui, vous pouvez le faire mais cela va être extrêmement difficile et vous causera probablement plus de douleur que de prendre la voie alternative.
Gary Rowe
2
@rvcoutinho Je n'ai pas utilisé Apache Shiro (alias Apache Security) mais j'imagine que ce serait une bonne solution au problème de sécurité partagée. Envisagez certainement de vous intégrer à OpenID et OAuth2 plutôt que de lancer votre propre protocole pour obtenir la même chose. JBoss Cache est de leur propre aveu dans une impasse remplacée par Infinispan qui semble plutôt complexe. Vous voudrez peut-être jeter un œil au site de l'application à douze facteurs pour avoir un aperçu d'une solution plus simple et plus évolutive.
Gary Rowe
2

C'est quelque chose qui, à mon avis, manque de fonctionnalité dans la spécification JEE EAR - la possibilité de partager des sessions Web sur plusieurs archives Web liées dans un EAR.

Les serveurs d'applications tels que Weblogic ont des implémentations non standard pour cette fonctionnalité.

Martijn Verburg
la source
C'était mon opinion jusqu'à présent. J'essayais de comprendre pourquoi le choix mentionné avait été fait.
rvcoutinho
1

Eh bien, AFAIKS, il n'y a aucune vraie raison pour laquelle vous voudriez faire ça. Un WAR est une application Web autonome, avec ses propres étendues (spécifiques à l'application Web) (comme l'étendue de la session). Si vous avez besoin de partager des fonctionnalités (code Java, pages JSP, fichiers CSS), entre plusieurs fichiers WAR, vous avez la possibilité beaucoup plus judicieuse de les empaqueter sous forme de fichiers JAR et de les déployer sur votre serveur d'applications. Un package WAR est une solution de packaging plus complexe, conçue pour encapsuler quelque chose de différent d'un simple "code / fonctionnalité commun". Le JAR est un format plus simple ET est conçu pour empaqueter et partager du code et des fonctionnalités. Pourquoi voudriez-vous utiliser un emballage plus complexe et non spécialement conçu pour cela pour partager quelque chose, alors que vous avez déjà un format de paquet plus simple et plus adapté à ce paquet.

Shivan Dragon
la source
Je suis d'accord avec toi. Mais seulement lorsqu'il s'agit de ressources générales. Mais, pour une application de connexion unique, je devrais partager des informations spécifiques à la session (sur l'utilisateur connecté). Et je ne vois aucune raison pour laquelle ce serait contraire à la spécification.
rvcoutinho
2
Parce que la portée de la session n'est pas faite pour partager les données utilisateur actuelles entre différentes applications. Et parce que l'authentification unique implique plus que l'inspection des attributs de portée de session. Vous pouvez créer et empaqueter du code en dehors de votre guerre (et qui ne dépendrait pas de votre guerre, mais plutôt que la guerre en dépende) qui accéderait aux attributs de portée de session si vous le vouliez (comme un filtre), mais la meilleure solution à mon humble avis serait d'avoir une application de façade ou une configuration de serveur distincte qui traite de l'authentification et accorde l'accès à d'autres applications (déployées par la guerre).
Shivan Dragon
Je serais de nouveau d'accord avec vous. Pourtant, la spécification JavaEE (utilisant JAAS) contient les informations utilisateur dans le cadre de la session HttpSession, qui s'oppose à cette approche. L'une des raisons pour lesquelles j'ai envisagé d'utiliser Shiro (il maintient une session orthogonale) à la place.
rvcoutinho
Quoi qu'il en soit, merci pour la réponse. Je n'ai toujours pas de réponse définitive à ma question, mais tout ce que vous avez dit est pertinent. +1
rvcoutinho
@rvcoutinho bien, c'est mon avis sur la question, désolé, cela ne vous a pas été plus utile.
Shivan Dragon
0

Je pense que cela a été fait exprès, pour éviter que les différentes applications Web n'écrasent accidentellement les informations de session des autres. Cela peut être utile dans votre cas, mais en général, vous ne voulez pas que les utilisateurs bloquent l'application ou augmentent leurs privilèges simplement parce qu'ils utilisent deux applications Web en même temps. Il n'est pas exactement difficile de partager explicitement des informations entre des applications Web; créez simplement une classe avec un HashMap statique, utilisez des GUID comme clés et transférez-les dans le cadre du paramètre URL ou HTTP.

user281377
la source
Merci. En fait, je ne parlais pas de partager toute la session entre chaque application, mais des informations de session spécifiques (en tant qu'informations utilisateur) en cas de besoin. Peut-être que je n'étais pas clair. Des suggestions pour le rendre plus clair?
rvcoutinho