Perché le WAR non possono condividere le informazioni sulla sessione?


11

Ho visto diversi sviluppatori alla ricerca di una soluzione a questo problema: accedere alle informazioni sulla sessione da una WAR diversa (anche se all'interno della stessa EAR) - ecco alcuni esempi: un modo per condividere lo stato della sessione tra diverse applicazioni in Tomcat? , Accedi alla sessione di un'altra applicazione web , file WAR diversi, risorse condivise , Tomcat: come condividere i dati tra due applicazioni? , Che cosa fa l'attributo crossContext in Tomcat? Abilita la condivisione della sessione? e così via...

Da tutto quello che ho cercato, ci sono alcune soluzioni specifiche a seconda del contenitore, ma è in qualche modo " contrario alle specifiche ". Ho anche esaminato le specifiche Java EE senza alcuna fortuna nel trovare una risposta.

Alcuni sviluppatori parlano dell'accoppiamento tra le applicazioni Web, ma tendo a non essere d'accordo. Qual è il motivo per cui si dovrebbero tenere le WAR all'interno della stessa EAR se non si accoppiano? Gli EJB, ad esempio, sono accessibili localmente (anche se all'interno di un altro JAR EJB all'interno dello stesso EAR).

Più specificamente, uno dei miei WAR gestisce l'autenticazione e l'autorizzazione e vorrei condividere queste informazioni con altri WAR (nella stessa EAR). In passato sono riuscito a risolvere problemi simili confezionando WAR come JAR e inserendoli in un singolare progetto WAR (WEB-INF / lib). Eppure questa soluzione non mi piace (richiede uno sforzo enorme per la denominazione dei servlet e così via).

E nessuna soluzione ha risposto alla prima (e più importante) domanda: perché i WAR non possono condividere le informazioni sulla sessione?


1
Non sono sicuro del motivo per cui questo è stato sottoposto a downgrade, oltre a quello che potrebbe adattarsi meglio alla SO.
NateDSaint il

3
"In conformità con la specifica API servlet 2.3, il gestore sessioni supporta l'ambito della sessione solo dal modulo Web. Solo i servlet nello stesso modulo Web possono accedere ai dati associati a una determinata sessione." Questo può essere visto di nuovo in HttpSession - "Le informazioni sulla sessione sono incluse solo nell'applicazione web corrente (ServletContext), quindi le informazioni memorizzate in un contesto non saranno direttamente visibili in un altro." - Ciò è contrario alle specifiche.

(meglio, collegamento corrente per HttpSession )

@MichaelT, grazie. Ma non risponde ancora al perché.
rvcoutinho,

@NateDSaint Anche se la domanda è collegata a tecnologie specifiche, ho pensato che fosse più probabile che fosse una domanda concettuale. Quindi, ho deciso per i programmatori.
rvcoutinho,

Risposte:


7

Tratta una EAR come una macchina pseudo-virtuale

Una EAR è semplicemente una raccolta di file WAR che condividono configurazioni e librerie comuni, generalmente da JAR. Ciò consente di gestire più facilmente una raccolta di servizi interdipendenti all'interno di un contenitore di applicazioni. Quindi puoi pensare a una EAR come a una semplice forma di macchina virtuale una volta distribuita nel suo contenitore.

Allo stesso modo in cui un processo su una macchina virtuale non può influire su un altro, lo stesso vale per un EAR. Tutte le GUERRE sono isolate per proteggere il loro stato interno.

Autenticazione in scala

In generale, le applicazioni Web devono essere apolidi per scalare bene. Avere molte informazioni nella sessione è un anti-pattern che impedisce questo. Ciò porta a un conflitto tra la natura apolide di HTTP e la necessità di mantenere un'esperienza utente rapida e personalizzata. L'autenticazione è un caso d'uso classico ed è prevalente nelle API chat che richiedono molte richieste autenticate per fornire funzionalità all'utente finale.

Single Sign On e Single Sign Off necessitano di un'attenta segnalazione per funzionare correttamente (considerare il Sign Off parziale), in particolare quando è presente il ridimensionamento orizzontale. La semplice condivisione dello stato della sessione non è quasi mai una buona soluzione e un approccio migliore consiste nell'utilizzare un singolo punto di riferimento per le informazioni utente a cui hanno accesso tutti i nodi del cluster.

Concentrarsi sull'accesso rapido alle informazioni pertinenti memorizzato nella cache produrrà risultati molto più scalabili rispetto a qualche soluzione complessa e fragile di condivisione delle sessioni.


Grazie, @GaryRowe. Questa è la risposta che stavo cercando. Ad ogni modo, non potrebbe essere quello che lo sviluppatore deve decidere?
rvcoutinho,

Un'altra domanda: pensi che JBoss Cache potrebbe essere una buona soluzione? Hai mai sentito parlare di Apache Shiro (e del suo clustering di sessioni)? Che ne dici?
rvcoutinho,

@rvcoutinho Lo sviluppatore dell'applicazione decide come vengono gestiti i processi nel kernel Linux? È una definizione simile di una domanda: sì, potresti farlo, ma sarà estremamente difficile e probabilmente ti causerà più dolore che prendere la strada alternativa.
Gary Rowe,

2
@rvcoutinho Non ho usato Apache Shiro (aka Apache Security) ma immagino che sarebbe una buona soluzione al problema di sicurezza condiviso. Sicuramente considera l'integrazione con OpenID e OAuth2 piuttosto che implementare il tuo protocollo per ottenere la stessa cosa. JBoss Cache è per sua stessa ammissione in un vicolo cieco che viene sostituito con Infinispan che sembra piuttosto complesso. Potresti dare un'occhiata al sito dell'app Twelve-Factor per dare un'occhiata a una soluzione più semplice e scalabile.
Gary Rowe,

2

È qualcosa a cui ritengo manchi la funzionalità della specifica EEE JEE: la possibilità di condividere sessioni Web su più archivi Web associati all'interno di una EAR.

I server di app come Weblogic hanno implementazioni non standard per questa funzionalità.


Finora questa era la mia opinione. Stavo cercando di capire perché fosse stata fatta la scelta citata.
rvcoutinho,

1

Bene, AFAIKS, non c'è un vero motivo per cui ti piacerebbe farlo. Una WAR è un'applicazione web autonoma, con i propri ambiti (specifici dell'applicazione Web) (come l'ambito della sessione). Se devi condividere funzionalità (codice Java, pagine JSP, file CSS), tra più WAR hai la possibilità molto più sensata di comprimerli come file JAR e distribuirli nel tuo server delle applicazioni. Un pacchetto WAR è una soluzione di imballaggio più complessa e progettata per incapsulare qualcosa di diverso dal semplice "codice / funzionalità comune". Il JAR è un formato più semplice ED è progettato per il packaging e la condivisione di codice e funzionalità. Perché vorresti utilizzare un packaging più complesso e non specifico per quel progetto per condividere qualcosa, quando hai già un formato di pacchetto più semplice e più adatto a quel pacchetto?


Sono d'accordo con te. Ma solo quando si tratta solo di risorse generali. Ma, per una singola applicazione di accesso, avrei bisogno di condividere informazioni specifiche della sessione (sull'utente registrato). E non vedo alcun motivo per cui ciò sarebbe contrario alle specifiche.
rvcoutinho,

2
Poiché l'ambito della sessione non viene creato per condividere i dati dell'utente corrente tra diverse applicazioni. E poiché SSO implica più che ispezionare gli attributi dell'ambito della sessione. Puoi creare e impacchettare il codice al di fuori della tua guerra (e che non dipenderebbe dalla tua guerra, ma piuttosto far dipendere da essa) che accederà agli attributi dell'ambito della sessione se lo desideri (come un filtro), ma la soluzione migliore sarebbe IMHO avere un'applicazione di facciata separata o una configurazione server che si occupa dell'autenticazione e conceda l'accesso ad altre applicazioni (schierate in guerra).
Shivan Dragon,

Sarei di nuovo d'accordo con te. Tuttavia, la specifica JavaEE (utilizzando JAAS) contiene le informazioni dell'utente come parte di HttpSession, che si oppone a questo approccio. Uno dei motivi per cui ho preso in considerazione l'uso di Shiro (mantiene una sessione ortogonale).
rvcoutinho,

Comunque, grazie per la risposta. Non ho ancora una risposta definitiva alla mia domanda, ma tutto ciò che hai detto è pertinente. +1
rvcoutinho il

@rvcoutinho bene, questa è la mia opinione in merito, mi dispiace che non ti sia stato più utile.
Shivan Dragon il

0

Penso che ciò sia stato fatto apposta, per evitare che diverse app Web sovrascrivessero accidentalmente le informazioni sulla sessione. Potrebbe essere utile nel tuo caso, ma in generale, non vuoi che gli utenti rompano l'app o aumentino i loro privilegi solo perché usano due app Web contemporaneamente. Non è esattamente difficile condividere esplicitamente informazioni tra app Web; basta creare una classe con una HashMap statica, utilizzare i GUID come chiavi e trasferirli come parte del parametro URL o HTTP.


Grazie. In realtà, non stavo parlando della condivisione dell'intera sessione tra tutte le applicazioni, ma di informazioni specifiche sulla sessione (come informazioni sull'utente) quando necessario. Forse non ero chiaro. Qualche suggerimento su come renderlo più chiaro?
rvcoutinho,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.