2014-06-10 19 views
23

Sto cercando di utilizzare Spring Security per un'applicazione Spring MVC che sarà strettamente un servizio Web JSON. Ho fatto qualche ricerca e letto alcuni articoli ma non ho trovato nulla di veramente completo. Voglio che l'applicazione sia completamente stateless e usi l'autenticazione basata su token. Non voglio che l'applicazione Spring MVC abbia moduli o moduli usati per l'autenticazione. Deve richiedere rigorosamente richieste e dati in JSON e restituire le risposte JSON.Autenticazione token di sicurezza Spring - Servizio JSON RESTful

Ci sarà un'applicazione client JS angolare che dovrà inviare nome utente e password e ottenere il token dall'applicazione da utilizzare in richieste sequenziali. Ad un certo punto potrebbero esserci client Android che accedono a questo servizio web.

Suppongo che Spring Security abbia internamente la possibilità di mappare un token a una sessione utente, ovvero che conosca token XXXXXXXXXXXX è utente amministratore Bob e token AAAAAAAAAA è utente standard Joe. Tuttavia non ho molta esperienza con Spring Security, quindi non so come tutto questo si riunisca. Voglio comunque essere in grado di utilizzare annotazioni protette su controller e metodi di servizio.

C'è un modo per farlo in Spring Security?

Questa domanda sembra essere un buon punto di partenza ma non sono sicuro che funzionerà come l'ho immaginato RESTful Authentication via Spring.

+0

controllare questo URL potrebbe essere utile https://github.com/srinivas1918/spring-rest-security. Inoltre è necessario aggiungere login basato su modulo anche alla configurazione. –

risposta

18

Questo sarà un buon punto di partenza con Spring-Rest-Boilerplate.

  1. Per la prima volta è necessario utilizzare l'autenticazione HTTP di base e poi login (inviare nome utente/password) e questo restituirà il token.
  2. Nella richiesta successiva verrà utilizzato questo token per l'autenticazione.
  3. Sarà necessario aggiungere un filtro alla catena che eseguirà l'autenticazione in base a un token.

Devi arrivare con un formato token e la crittografia per lo stesso. È idealmente necessario mantenere una scadenza anche per il token, la scadenza insieme al nome utente potrebbe essere una parte del token.Utilizzare l'algoritmo di crittografia con una funzione di hash crittografica come MD5 e ottenere l'hash dell'intero Token.

Edit: Come sottolineato da Maciej Stępyra MD5 sembra essere rotto e la sua consiglia di utilizzare una più forte funzioni di hash come SHA-256.

sicurezza Primavera di default vi reindirizza a una pagina di login, ma questo non ha senso in caso di REST in modo da utilizzare una consuetudine AuthenticationEntryPoint in config (Rif codice di esempio github).

stavo usando questo formato per la mia Token: token:username:hash:expiry

hash = MD5 (nome utente + MagicKey)

scadenza = CURRENT_TIMESTAMP + mins_to_expiry

<security:http realm="Protected API" use-expressions="true" auto-config="false" create-session="always" entry-point-ref="**CustomAuthenticationEntryPoint**"> 
     <security:custom-filter ref="**authenticationTokenProcessingFilter**" position="PRE_AUTH_FILTER" /> 
     <security:intercept-url pattern="/**" access="isAuthenticated()" /> 
</security:http> 

NB: Grazie dhavaln per il codice. Ho usato questo come riferimento e ho sviluppato una cosa simile.

+0

Questo sembra un buon punto di partenza. Grazie! Spring Security esegue internamente il mapping del token a una sessione in modo che tu possa ancora eseguire operazioni come @Secured (value = {"ROLE_ADMIN"})? – greyfox

+0

Sì, è possibile utilizzare, ma non è necessario che la sessione REST sia senza stato e configurare 'create-session =" stateless "'. Nel tuo 'TokenAuthenticationFilter' cercare i dettagli utente e creare un' UsernamePasswordAuthenticationToken' e usare 'SecurityContextHolder.getContext(). SetAuthentication (autenticazione);' – M4ver1k

+0

Come si rinnova il token? Come se lo avessi impostato in modo che scada dopo 15 minuti e hai inviato richieste per 15 minuti interi, costringi l'utente a registrarsi di nuovo? –

1

"Voglio l'applicazione per essere completamente senza stato"

mi piacerebbe riconsiderare ciò che si sta cercando di fare. C'è un motivo per cui non riesci a trovare buoni esempi della tua soluzione: semplicemente non puoi avere un'applicazione che sia sia stateless che sicura. Inoltre, se stai memorizzando i token da qualche parte, non sei apolidi. Anche se non si memorizzano i token (come l'utilizzo di JWT per codificarli), è necessario proteggersi dagli attacchi CSRF se gli utenti accederanno a ciò in un browser web. Se segui la tua strada, aspettati di scrivere un sacco di codice di sicurezza personalizzato (che è una brutta cosa). Vedere una discussione di questo qui: https://spring.io/blog/2015/01/12/the-login-page-angular-js-and-spring-security-part-ii

1

Nel mio caso ho trovato più facile sostituire il org.springframework.security.web.context.SecurityContextRepository in org.springframework.security.web.context.SecurityContextPersistenceFilter con un'implementazione che condivide il SecurityContext tra diversi nodi Tomcat. Il client continua a inviare un token jsessionid-like, ma posso eseguire un semplice bilanciamento del carico round-robin e non devo preoccuparmi della replica della sessione.

Problemi correlati