Partager des données entre plusieurs appli-web

Partager des données entre plusieurs appli-web - Java - Programmation

Marsh Posté le 18-08-2004 à 15:27:43    

Je voudrais partager des données enter plusieurs appli-web installées dans des contextes différents, tournant sur un même serveur (même moteur de servlet aussi bien sur).
J'explique la situation : dans ma boite, je développe plusieurs appli-web. Chacune nécessite une identification utilisateur. Le système de cette identification est simple : une table de correspondances entre code utilisateurs et mots de passe. Je voudrais centraliser cette identification en une appli-web indépendante, qui jouerai ensuite le rôle de "portail", permettant de délester toutes les autres appli de la vérification du mot de passe. Pour ça, le seul moyen sur me semble être un partage de données entre l'appli "portail" et les autres appli (je vais évidement pas utiliser un paramète HTTP pour indiquer que l'utilisateur est passé par le portail !)
Je prend toutes les idées, en vrac...

Reply

Marsh Posté le 18-08-2004 à 15:27:43   

Reply

Marsh Posté le 18-08-2004 à 16:51:46    

SSO est fait pour toi

Reply

Marsh Posté le 18-08-2004 à 16:57:31    

SSO, késako ? (je file googeuliser !)

Reply

Marsh Posté le 18-08-2004 à 17:02:49    

Ha, ouais. En gros ça permet de faire ce que je veux. Le problème c'est que c'est payant (si on veut l'intégrer à une solution commerciale). Du coup on va plutôt développer le machin en interne je pense.

Reply

Marsh Posté le 18-08-2004 à 17:19:40    

El_gringo a écrit :

J(je vais évidement pas utiliser un paramète HTTP pour indiquer que l'utilisateur est passé par le portail !)


Et pourquoi pas ?
c'est ce qu'on fait, nous...  
 
genre en parametre, tu mets la clef de session...
 
1. Tu te loggues sur le portail :
 - tu associes le sessionId a l'utilisateur, par exemple en bdd
2. Tu lances une appli avec le sessionId du portail en param
3. L'appli récupere le nom d'utilisateur avec ce param
4. Si y'a pas de nom associé, y'a pas d'utilisateur logué
 
Avec en prime sur le portail un SessionListener qui va nettoyer la base quand la session est invalidée.

Reply

Marsh Posté le 19-08-2004 à 09:20:31    

L'intéret, c'est de ne pas gérer l'identification dans chaque appli. Là, on la gère encore, en allant vérifier en base de données, etc. L'idéal serait d'obtenir directement le code utilisateur du connecté, à partir d'une session partagée.

Reply

Marsh Posté le 19-08-2004 à 10:16:26    

RMI ?


---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 19-08-2004 à 11:20:05    


 
Jamais utilisé. J'en connais même pas le fonctionnement. C'est un appel distant de méthodes Java, c'est ça ? Une sorte de web-service réservé au Java ?
Et c'est lourd ? (à l'exécution et à la mise en place)

Reply

Marsh Posté le 19-08-2004 à 14:19:52    

c'est de la communication réseau entre application de façon transparente.
Ca permettrait de faire un serveur d'authetification : le gars se log sur ce serveur. Les autres applis peuvent demander si le gars est logué.
 
De toute façon, t'as pas 36 façon de faire : soit t'es dans la même JVM et tu peux partager un objet (quoique dans des web-app t'es emmerdé avec les histoire de classloader indépendants), soit c'est pas le cas est faut communiquer par réseau (ou système de fichier, ou autre truc dans le genre).


---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 19-08-2004 à 14:23:50    

benou a écrit :

c'est de la communication réseau entre application de façon transparente.
Ca permettrait de faire un serveur d'authetification : le gars se log sur ce serveur. Les autres applis peuvent demander si le gars est logué.


ce qui au final donne une autre implémentation de ma solution  [:sinclaire]

Reply

Marsh Posté le 19-08-2004 à 14:23:50   

Reply

Marsh Posté le 19-08-2004 à 14:30:49    

Ha, ben voila, je m'disais que ça pouvait exister. J'crois que j'ai trouvé ce que je cherchais.
http://www.fwd.at/tomcat/sharing-s [...] howto.html

Reply

Marsh Posté le 19-08-2004 à 16:54:55    

Merci à vous 2 pour les suggestions.

Reply

Marsh Posté le 19-08-2004 à 17:01:01    

El_gringo a écrit :

Ha, ben voila, je m'disais que ça pouvait exister. J'crois que j'ai trouvé ce que je cherchais.
http://www.fwd.at/tomcat/sharing-s [...] howto.html


pour moi, y a que la solution de la sérilisation et du ctockage qui marche, parce que tant que tu stockes des objets classiques de l'API java dans le context, ca va marcher, mais vas y stocker un objet loadé depuis une web app, et essaye de l'utiliser depuis une autre web-app, ben tu vas avoir des sacrés couilles : les Class ne seront pas les même => pas compatible.
 
La seule solution que je connaisse pour résoudre ca est de passer par la sérialisation / désérialisation. Après, ca peut marcher quelque soit le systême de sauvegarde ou de transfert : au sein de la même jvm (la technique du context fonctionnera), en RMI (ce sera transparent), en BDD, etc ...
 
Je trouve la solution RMI la plus élégante. La solution BDD la plus "standard" et la solution du context la plus simple.


---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 19-08-2004 à 18:14:38    

Je vote pour la solution RMI qui est pas mal...
Sinon, pkoi pas un service web ?

Reply

Marsh Posté le 20-08-2004 à 08:46:48    

oliv5 a écrit :

Je vote pour la solution RMI qui est pas mal...
Sinon, pkoi pas un service web ?


 
Parce que c'est lourd à mettre en place, lourd dans le fonctionnement, et c'est donc environ 1000 fois moins simple qu'un contexte partagé dans cette situation.
 
EDIT : s'il n'en est pas de même pour RMI, c'est plus standard qu'un context partagé, et donc préférable. J'y jetterais un oeil.


Message édité par El_gringo le 20-08-2004 à 08:49:53
Reply

Marsh Posté le 20-08-2004 à 08:53:33    

benou a écrit :

La seule solution que je connaisse pour résoudre ca est de passer par la sérialisation / désérialisation. Après, ca peut marcher quelque soit le systême de sauvegarde ou de transfert : au sein de la même jvm (la technique du context fonctionnera)

c'est à dire !?
 

benou a écrit :


Je trouve la solution RMI la plus élégante. La solution BDD la plus "standard" et la solution du context la plus simple.


- RMI, sans doute la + élégante
- BDD : aucun intéret, car le principe, c'est de délester toutes les appli de l'identification. Si en revanche, chacune doit aller voir en BD si l'utilisateur est connecté, on perd tout l'intéret de la chose.
- La solution du context : celle vers laquelle on est en train d'aller, bien que rien ne soit définitif.

Reply

Marsh Posté le 20-08-2004 à 09:25:39    

El_gringo a écrit :

c'est à dire !?


tu charges un objet à toi dans une webapp et tu le sauve dans un context ("/context1" ):

Code :
  1. this.getServletContext().setAttribute("monObjet", new MonObjet());


 
dans un autre contexte ("/context2" ), tu essayes de le récupérer :

Code :
  1. ServletContext autreContext = this.getServletContext().getContext("/context1" );
  2. MonObjet monObjet = (MonObjet) autreContext .getAttribute("monObjet" );


et ben ca ca va te cracher une ClassCastException. Alors que si l'objet que tu mets dedans est une String, ca va fonctionner.
La raison est que c'est des ClassLoader différents qui ont chacun chargé la classe MonObjet dans chaque contexte => pour la JVM c'est des classes différentes => les instances de ces objets ne sont pas compatibles => le cast plante.
 
Avec des String ou des objets "classiques" de l'API ca va marcher parce que ces classes n'auront pas été chargées par le classloader de chaque web-app, mais auparavant car elles sont utilisées au sein du moteur de sevlet => elles auront été chargé par le parent (ou plutot un ancêtre) des classloader des webapp => elles seront compatibles.
 
Tu vois le soucis ? les objets pour lesquels ca va marcher est dépendant du moteur de servlet, voir de la version du moteur de servlet que tu vas utiliser.
 
En utilisant la sérialisation par contre ca va marcher car au moment de la désérialisation, c'est le classloader de la webapp qui recréé l'objet à partir du flux binaire (qui lui est forcément commun à tous les classloader si la classe est la même).  
 
donc en gros faut faire ca :  
/context1 : on sérialize l'objet et on sauve la donnée binaire

Code :
  1. ByteArrayOutputStream data = new ByteArrayOutputStream();
  2. ObjectOutputStream stream = new ObjectOutputStream(data);
  3. stream.write(new MonObjet());
  4. stream.flush(); // pas sûr que ce soit utile ...
  5. this.getServletContext().setAttribute("monObjetSerialize", data.toByteArray());


 
/context2 : on récupère la donnée binaire et on désérialize

Code :
  1. ServletContext autreContext = this.getServletContext().getContext("/context1" );
  2. byte[] serializedObject = (byte[]) autreContext .getAttribute("monObjetSerialize" );
  3. ByteArrayInputStream data = new ByteArrayInputStream(serializedObject);
  4. ObjectInputStream stream = new ObjectInputStream(data);
  5. MonObjet monObjet = (MonObjet) stream.readObject();



---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 20-08-2004 à 09:26:17    

capiché ?


---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 20-08-2004 à 09:31:48    

y a une autre solution aussi, c'est de ne jamais recaster ton objet et de l'utiliser avec de l'invocation dynamique. ca marchera ...


Message édité par benou le 20-08-2004 à 10:17:55

---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 20-08-2004 à 10:02:41    

Compris. Et c'est très très interressant ce que tu me dis là. D'autant que j'ai jeté un oeil à RMI : pas interressant dans mon cas, car impliquant trop de changements dans l'existant.

Reply

Marsh Posté le 20-08-2004 à 10:03:05    

Merci beaucoup, je vais voir ce que je peux faire avec ça.

Reply

Marsh Posté le 20-08-2004 à 15:21:20    

Un ejb container commum avec tte les appli web et un statefull qui garde le contexte de chacun

Reply

Marsh Posté le 20-08-2004 à 15:24:22    

savory a écrit :

Un ejb container commum avec tte les appli web et un statefull qui garde le contexte de chacun


et comment tu le partages entre tes applications ton statefull ?


Message édité par benou le 20-08-2004 à 15:24:32

---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 20-08-2004 à 15:31:49    

Bah comme pour tout les ejb via un stub et pendant une demande d'auth l'application server demande l'etat du contexte de l'utilisateur peu importe d'ou il vient ...
Les ejb sont fait pour fonctionner sur des architectures distribuées et je pense que c'est le cas ici.
 
Sinon la solution jndi me parait bonne aussi apres ca depend de l'architecture derriere

Reply

Marsh Posté le 20-08-2004 à 15:39:17    

savory a écrit :

Bah comme pour tout les ejb via un stub et pendant une demande d'auth l'application server demande l'etat du contexte de l'utilisateur peu importe d'ou il vient ...


Ben nan. A statefull ca se créé pour un client donné. comment tu veux le faire parvenir à autre client si ils n'ont pas le moyen de coimmuniquer entre eux. Et client ne pourra pas adresser le même statefull qu'un autre client à moins justement qu'ils se passent la référence du stub (ce qui ici n'est pas faisable).  
Ca pourrait marcher avec un entity bean en récupérant le bean avec un findBy.
 
Mais ca revient à utiliser un BDD ...
 

savory a écrit :

Sinon la solution jndi me parait bonne aussi apres ca depend de l'architecture derriere


pas con.
 
D'ailleur je me demande comment ca se passe en JNDI pour ces histoires de classloaders ...


---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 28-08-2004 à 15:21:01    

savory a écrit :

Un ejb container commum avec tte les appli web et un statefull qui garde le contexte de chacun


 
pour un statefull session bean deux thread ne peuvent pas l utiliser en meme temps, donc il est deconseille de la partager entre plusieurs clients (webapp) meme si l utilisateur n est cense n utiliser qu une seule webapp en meme temps.

Reply

Marsh Posté le 28-08-2004 à 15:38:38    

senternal a écrit :

SSO est fait pour toi


 
En fait sso est une bonne solution mais cela force a utiliser la securite integree a j2ee. En analysant ce que fait sso il est facile de reproduire la meme chose et d'en tirer une solution efficace : SSO partage le principal a travers plusieurs webapp a l aide d un cookie.
 
Ce qui est facile a faire : qd l utilisateur s'identifie, on cree un identifiant unique et on met dans un map partagee a travers toutes les applications l'utilisateur authentifie (ou login/mot de passe).
 
Le plus facile est de faire cela avec un servlet filter que l on place devant toutes les applications partageant le meme user.
 
Pour partager une map : utiliser un singleton qui contient une hashmap synchronizee of course. Une chose importante a utiliser ici est une WeakHashMap wrappee par un Collections.synchronizedMap(). C'est la que c est un peu astucieux car la clee qui sert dans la map (l'UUID) doit etre present dans toutes les sessions afin que l'entree reste dans la map).
Quand toutes les sessions ont etees expirees ceci permettra a la map de se nettoyer toute seule et ainsi d'eviter que les objet User ne passent pas au garbage collection et evitant ainsi un belle fuite de memoire.
 
Il faut faire attention a ce que la classe partagee soit visible par toutes les webapp, i.e elle est chargee dans un classloader parent a toutes les webapp.
 
Pour generer un ID unique, il est possible d utilser l algo UUID.
 
Quand un client arrive le code dans le servlet filter s apparente a :
 
recuperer le cookie d'identification
aller piocher dans la map partagee l'user
mettre l'user dans la session http
faire suivre la requete a la servlet
 
Quand un utilisateur s'identifie :
recuperer l objet User
generer un UUID et le mettre comme cookie
mette dans la Map le couple (UUID, user)
mettre dans la session l'UUID.

Reply

Marsh Posté le 02-09-2004 à 14:54:44    

et pourquoi pas une appli qui logue les gens et met un objet dans la session http, avec les accès et autres...
L'appli check le mdp sur une base/annuaire, vérifie les droits d'accès, et hop !
il suffit que toutes tes autres applis redirigent d'abord vers ton appli de loggin
 
(j'ai pas tout lu, hein, alors pas taper trop fort)


---------------
HFR - Mes sujets pour Chrome - Firefox - vérifie les nouveaux posts des topics suivis/favoris
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed