Uso programmatico di Spring Security
-
06-07-2019 - |
Domanda
Sto usando Wicket con il Wicket Auth Project per il mio livello di presentazione e quindi l'ho integrato con Spring Sicurezza. Questo è il metodo che Wicket chiama per autenticazione per me:
@Override
public boolean authenticate(String username, String password) {
try {
Authentication request = new UsernamePasswordAuthenticationToken(
username, password);
Authentication result = authenticationManager.authenticate(request);
SecurityContextHolder.getContext().setAuthentication(result);
} catch (AuthenticationException e) {
return false;
}
return true;
}
I contenuti (all'interno) della mia configurazione XML di Spring Security sono:
<http path-type="regex">
<form-login login-page="/signin"/>
<logout logout-url="/logout" />
</http>
<global-method-security secured-annotations="enabled" />
<authentication-manager alias="authenticationManager"/>
<authentication-provider user-service-ref="userService">
<password-encoder ref="bcryptpasswordencoder" />
</authentication-provider>
La sezione 2.3.6. Session Protection Attack Protection della documentazione di riferimento dice:
Gli attacchi con fissazione di sessione rappresentano un rischio potenziale laddove possibile per un malintenzionato malintenzionato creare un sessione accedendo a un sito, quindi convincere un altro utente con cui effettuare l'accesso la stessa sessione (inviando loro a collegamento contenente l'identificatore di sessione come parametro, ad esempio). Primavera La sicurezza protegge da questo automaticamente creando un nuovo sessione quando un utente accede. Se si non richiede questa protezione, o esso è in conflitto con qualche altro requisito, puoi controllare il comportamento usando la protezione della fissazione della sessione attributo on, che ha tre opzioni:
- migrateSession: crea una nuova sessione e copia quella esistente attributi di sessione per la nuova sessione. Questo è il valore predefinito.
- nessuno - Non fare nulla. La sessione originale verrà mantenuta.
- newSession - Crea un nuovo " clean " sessione, senza copiare il file dati di sessione esistenti.
L'autenticazione funziona, ma dato che sono abbastanza nuovo in Spring Security ho alcune domande alle quali ho bisogno di risposte:
- Normalmente per l'accesso, POSTRO le informazioni di autenticazione su
j_spring_security_check
e consentire a Spring Security di eseguire il vero codice di autenticazione. Vorrei avere protezione contro gli attacchi di fissazione di sessione, lo avrò quando eseguo un accesso programmatico come faccio? E se no, cosa dovrei fare per ottenerlo? - Come eseguo il logout programmatico?
- Dato che userò il login e il logout programmatici, come faccio a disabilitare Spring dall'intercettare quegli URL?
Aggiornamento:
Per la protezione dagli attacchi di fissazione della sessione sembra che sia necessario chiamare il metodo nella classe SessionUtils con la firma startNewSessionIfRequired (richiesta HttpServletRequest, boolean migrateAttributes, SessionRegistry sessionRegistry)
.
Come posso ottenere l'istanza SessionRegistry che devo trasmettere? Non riesco a trovare un modo per creare un ID alias per esso o come ottenerne l'ID o il nome.
Soluzione
Forse non è una risposta completa alle tue domande, ma forse potrebbe aiutarti.
Il codice che viene chiamato quando NON si utilizza l'accesso programmatico, ma uno standard è disponibile qui:
org.springframework.security.ui.webapp.AuthenticationProcessingFilter
Suppongo che tu sia stato ispirato da questo nel tuo codice. Sembra abbastanza simile.
Allo stesso modo il codice eseguito quando si accede a / j_spring_security_logout
nell'approccio standard, si trova qui:
org.springframework.security.ui.logout.LogoutFilter
LogoutFilter chiama più gestori. Il gestore che stiamo usando si chiama:
org.springframework.security.ui.logout.SecurityContextLogoutHandler
, quindi potresti chiamare lo stesso codice nel tuo approccio.
Altri suggerimenti
Sarai davvero aperto agli attacchi di fissazioni di sessione. Per ovviare a questo problema potresti essere di nuovo "ispirato". dal codice primavera. Per creare una nuova sessione avrai ovviamente bisogno dell'accesso alla httpsession, quindi potresti dover fare un po 'di refactoring.
Se vedi il metodo SessionUtils
. startNewSessionIfRequired
.
Questo eseguirà la migrazione dell'autenticazione in una nuova sessione. Potresti essere in grado di chiamare questo metodo direttamente oppure rifattate leggermente il codice.
Per quanto riguarda il logout programmatico non puoi andare troppo lontano semplicemente chiamando session.invalidate ()
quando devi disconnetterti. Questo farà tutto il necessario dal punto di vista della sicurezza generale, ma tieni presente che potresti dover ripulire alcune cose durante la sessione. Se hai un set di filtri molto complicato ecc. E devi assicurarti che l'utente sia disconnesso per il resto della richiesta, puoi aggiungere:
SecurityContextHolder.getContext().setAuthentication(null);
Per quanto riguarda l'intercettazione degli URL, potresti semplicemente impostarli su qualcosa di inutilizzato e ignorarlo! Non sono sicuro che puoi disattivare l'intercettazione nella configurazione - se vuoi davvero rimuoverlo, dai un'occhiata al AuthenticationProcessingFilter
- potresti personalizzarlo. Se lo fai, dovrai impostare manualmente l'xml di sicurezza di primavera e non usare gli spazi dei nomi forniti. Non è troppo difficile però: guarda qualche documentazione precedente e vedrai come farlo.
Spero che questo aiuti!
1) Logout programmatico
- chiama HttpServletRequest.getSession (false) .invalidate
- chiama SecurityContextHolder.clearContext ()
2) Di 'a Spring Security di NON intercettare determinati URL, questo tipo di dipende da come è impostato lo spazio dell'URL della tua applicazione. Se tutte le tue pagine (tranne / logIn e / logout) vivessero nel contesto / myApp, potresti farlo:
<http ....>
<intercept-url pattern="/myApp/**" ..>
....
</http>
Ho avuto un problema con l'accesso programmatico. Ho chiamato tutti i metodi authenticationManager.authenticate (...)
e SecurityContextHolder.getContext (). SetAuthentication (...)
ma ho avuto dei problemi con la Sessione. Ho dovuto aggiungere le seguenti righe per gestire correttamente la sessione:
HttpSession session = request.getSession();
session.setAttribute("SPRING_SECURITY_CONTEXT", SecurityContextHolder.getContext());
Questo non era chiaro dal codice di esempio pubblicato sopra. Per ulteriori informazioni, consulta http://forum.springsource.org/showthread.php?t=69761
Per eseguire il logout programmatico è anche possibile lanciare un org.springframework.security.core.AuthenticationException
. Ad esempio, SessionAuthenticationException
. In questo caso ExceptionTranslationFilter
avvia il logout.
Puoi provare
try {
HttpSession session = request.getSession(false);
if (session != null) {
session.invalidate();
}
SecurityContextHolder.clearContext();
} catch (Exception e) {
logger.log(LogLevel.INFO, "Problem logging out.");
}