Mentre questo tipo di funzionalità non è affatto banale da raggiungere, è infatti possibile senza modificare Spring.
Il codice effettivo è troppo grande per la pubblicazione, quindi cercherò di delineare il principio di base e lasciare la codifica a voi.
- Allunga la primavera del
SavedRequestAwareAuthenticationSuccessHandler
e implementare funzionalità per serializzare e scrivere l'oggetto a un cookie di sessione Authentication
con una portata globale. Vedere la documentazione per l'attributo nel tag <sec:http>
di Spring per ulteriori informazioni su come collegare . (Nota: se il problema si verificava tra più app Web su stesso dominio, si potrebbe ovviamente limitare l'ambito cookie al dominio corrente ).
- In tutte le tue applicazioni web, aggiungere un
web.xml
<filter>
definizione nome springSecurityFilterChain
e la classe org.springframework.web.filter.DelegatingFilterProxy
e <filter-mapping>
per il filtro con un modello URL di /*
Non è necessario creare il fagiolo reale, Primavera di sicurezza fornisce un implementazione predefinita per te.
- In tutte le tue applicazioni web, aggiungi al
web.xml
un <filter>
definizione nome singleSignonAuthenticationFilterChain
con classe org.springframework.web.filter.DelegatingFilterProxy
e corrispondente <filter-mapping>
per il filtro con un modello URL di /*
- Ora si aggiunge un nuovo bean chiamato
singleSignonAuthenticationFilterChain
, che dovrebbe indicare una classe che è implements Filter
.Nel metodo doFilter()
, verificare se esiste un attributo di sessione denominato SPRING_SECURITY_CONTEXT
. Se lo è , significa che è già stato effettuato il login. In alternativa, prendi il token serializzato Authentication
, deserializza e usa SecurityContextHolder.getContext().setAuthentication(authentication)
per autenticare l'utente con Spring. Ricorda inoltre di session.setAttribute("SPRING_SECURITY_CONTEXT", SecurityContextHolder.getContext())
oppure l'autenticazione occuperà ogni volta, il che non è necessario.
Una svolta a (4) è che se si scopre che non esiste un attributo chiamato SPRING_SECURITY_CONTEXT
, è possibile che l'utente si sia appena disconnesso dall'applicazione Web corrente. In questo caso deve essere disconnesso a livello globale, quindi in questo caso si desidera rimuovere il cookie contenente il token di autenticazione serializzato.
È un po 'complesso scrivere in un riepilogo di una pagina, ma spero che tu abbia un'idea generale. Attualmente lo abbiamo implementato in un'applicazione complessa composta da più applicazioni web e funziona bene.
Il meccanismo che si sta cercando si chiama single sign on. –
Un problema che devi risolvere (io penso di implementarlo da solo) è che l'ID di sessione è la maggior parte del tempo memorizzato in un cookie. Ma il browser assegna i cookie a un dominio, quindi dovrai gestire due diversi sessionId – Ralph
Il modo corretto per farlo è con SSO come ha detto Kurt. Tuttavia, poiché stai utilizzando OpenID e OAuth, puoi anche simulare il single sign on utilizzando un client HTTP per aprire l'altro sito Web e quindi restituire il cookie all'utente. Ho dovuto farlo in ambienti in cui abbiamo mixato le vecchie versioni di Acegi e le nuove applicazioni Spring Security. Non è bello, né la cosa giusta da fare, ma è veloce e porta a termine il lavoro. – Joe