2016-07-07 75 views
7

Voglio configurare un semplice provider OAuth2 basato su spring-boot, spring-security e spring-oauth2.Provider oauth2 di sicurezza stateless spring

Ho ottenuto tutto ciò che funziona su una singola macchina di istanza: per un'autorizzazione OAuth2, l'utente viene inviato a /oauth/authorize. La maggior parte degli utenti non ha effettuato l'accesso, quindi viene reindirizzata a /login per la sicurezza di primavera e quindi torna t /oauth/authorize per completare l'autorizzazione.

Nella configurazione predefinita, spring security imposta un cookie nel browser dell'utente con un id di sessione e memorizza i dati di sessione in memoria.

public static class SecurityConfiguration extends WebSecurityConfigurerAdapter { 
    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http 
      .authorizeRequests() 
      .and() 
      .formLogin() 
      .loginPage("/login") 
      .permitAll(); 
    } 
[...] 

Al fine di consentire il bilanciamento del carico e implementazioni blu-verde senza perdere le sessioni utente, (credo) che devo effettuare le seguenti operazioni:

  • Disattiva sessioni lato server - per un'API questo è solo responsabile dell'autorizzazione OAuth2 Non penso sia necessario avere un database condiviso per le sessioni.
  • Invece, abilitare un cookie remember-me contenente l'autenticazione dell'utente, temporanea durante l'autorizzazione.
  • Conservare l'URL di reindirizzamento per il /login reindirizzamento in un luogo diverso
    • E 'possibile conservare questo in forma di accesso o biscotto utente? O quale sarebbe un'alternativa "senza sessione"?
  • Disabilita CSRF (io so come farlo e OAuth2 ha auth_codes che penso hanno uno scopo simile. Solo per completezza.)

fa questo approccio ha senso? Quali cambiamenti sono necessari?

+0

Quello che ho fatto grosso modo è: (a) disabilitato CSRF (b) archivio URL di reindirizzamento nel cookie. Ho solo bisogno di una memoria per i codici oauth2. – Jan

risposta

0
  1. Dopo che l'utente fa un login al proprio fornitore, si genera un codice di autorizzazione che è inviare per l'applicazione client (attraverso il reindirizzamento (callback) url).

  2. Successivamente l'applicazione client effettua una richiesta al server per ottenere il token di accesso. In questa richiesta fornisce il codice di autorizzazione.

  3. A quel punto è necessario essere in grado di confrontare il codice di autorizzazione inviato dall'applicazione client con quello generato in primo luogo. Questo è dove hai bisogno di una memoria condivisa.

Se si guarda a questa sezione del protocollo section-4.1 avete bisogno della memoria condivisa tra il punto C e D.

Questo non può essere raggiunto con qualsiasi cosa al di fuori dei propri server, perché questo è il punto in cui si verifica che l'applicazione client sia autorizzata.

Simile è il caso con i token di accesso e aggiornamento più avanti nel processo.

Per il passo di accesso (punti A e B) - sembra corretto avere l'URL di reindirizzamento (e lo stato del client - vedere la sezione 4.1) all'interno del modulo di accesso. Se questo è l'unico posto in cui viene utilizzata la sessione, puoi liberartene. Ma avrai ancora bisogno di memoria condivisa (database condiviso) per il codice di autorizzazione.

+0

Ciao Alex, hai fornito una descrizione del flusso di OAuth2 ma non hai risposto alla mia domanda. Scusa, non posso darti la taglia per quello. – Jan

+0

Sì, non conosco i dettagli di cosa dovresti fare nel contesto della sicurezza di primavera, ma il mio punto era che avresti bisogno di un database condiviso in ogni caso. –

+0

Ok, ha senso, in realtà memorizzo il codice di autorizzazione in un database condiviso, in modo che la parte esista. Ma volevo controllare se posso liberarmi di un negozio di sessione generale. – Jan

0

Questo è un classico problema di archiviazione della sessione distribuita. Prima di tutto, i concetti di "sessione" (id di sessione e cookie) combinati con "senza stato" sono una specie di contraddizione.

OAuth2 si suppone che sia un "stateless" framework di autorizzazione delegata fornito si persiste la richiesta di ingresso iniziale (inclusi URL di reindirizzamento) sul lato server prima di generare il codice di accesso.

La perdita di tali dettagli nei cookie prima di ricevere le credenziali potrebbe esporvi agli exploit di sicurezza. Potresti ridurre il rischio assicurandoti che il cookie sia HttpOnly (non accessibile da JS) e protetto (rilasciato solo su httpS), ma non consiglierei comunque tale approccio.

Informazioni su altro punto: la funzionalità di ricordarsi di Spring Security è progettata per riportare solo le credenziali di autenticazione, non i dettagli sulle richieste di autorizzazione iniziali. Inoltre, le opzioni persistenti (PersistentTokenBasedRememberMeServices) supportano solo i sapori memory (single node) e jdbc per impostazione predefinita.

La regolazione di quelli per le vostre esigenze richiederà cambiamenti considerevoli. Fattibile ma richiede un grande sforzo

Nella mia esperienza, ci sono due alternative che viene in mente:

  1. Configurare le sessioni di appiccicoso che utilizzano un sistema di bilanciamento del carico di front- (es: haproxy, nginx, F5, ecc ...). La sessione utente sarà legata al nodo in cui sono state inoltrate le credenziali. L'implicazione è che se quel nodo scende; l'utente dovrà eseguire nuovamente l'autenticazione per creare nuovi token di accesso, ma i token di accesso già forniti dovrebbero essere validi se utilizzati contro altri nodi.

  2. Configurare/implementare una memoria di sessione Web distribuita trasparente. Alcuni fornitori di memoria di archiviazione distribuita (ad esempio: nocciola) offrono plugins che è configurato per i server delle applicazioni per renderlo trasparente per l'utente. C'è un po 'di overhead implicito in questo, ma non c'è quasi nessun codice aggiuntivo necessario per soddisfare il tuo requisito.

Problemi correlati