2013-08-01 12 views
8

Mi chiedevo cosa sto facendo male qui per autenticare un utente. Ho un'applicazione in cui l'utente esegue diversi passaggi per attivare il proprio account e, in tal caso, vorrei ignorare il modulo di accesso e portarli direttamente nella loro bacheca.Come posso autenticare a livello di codice utente con Spring Security utilizzando DaoAuthenticationProvider

Ecco ciò che la mia funzione di login automatico assomiglia:

protected void automatedLogin(String username, String password, HttpServletRequest request) { 

     try { 
      // Must be called from request filtered by Spring Security, otherwise SecurityContextHolder is not updated 
      CustomUserDetailsService udService = new CustomUserDetailsService(userDAO, request); 
      UserDetails uDetails = udService.loadUserByUsername(username); 
      UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(uDetails, password); 
      token.setDetails(new WebAuthenticationDetails(request)); 
      DaoAuthenticationProvider authenticator = new DaoAuthenticationProvider(); 
      Authentication authentication = authenticator.authenticate(token); 
      SecurityContextHolder.getContext().setAuthentication(authentication); 
     } catch (Exception e) { 
      e.printStackTrace(); 
      SecurityContextHolder.getContext().setAuthentication(null); 
     } 

    } 

devo utilizzare la classe DaoAuthenticationProvider come il mio provider di autenticazione. Ho verificato che sto ottenendo un modello UserDetails contenente le credenziali corrette, ID, ruoli di autorità, ecc

Quando si chiama il metodo autenticazione mi imbatto in un puntatore nullo da qualche parte lungo la strada nella classe DaoAuthenticationProvider:

org.springframework.security.authentication.AuthenticationServiceException a org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser (DaoAuthenticationProvider.java:109) a org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider. autenticare (AbstractUserDetail sAuthenticationProvider.java:132) a com.bosch.actions.BaseController.doAutoLogin (BaseController.java:659) . . . Causati da: java.lang.NullPointerException a org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser (DaoAuthenticationProvider.java:101)

Sono davvero non sono sicuro che è nullo, come I don' t avere il codice sorgente disponibile

Edit sono riuscito a trovare il codice sorgente qui - https://github.com/SpringSource/spring-security/blob/master/core/src/main/java/org/springframework/security/authentication/dao/DaoAuthenticationProvider.java

sono stato in grado di aggirare il puntatore nullo impostando esplicitamente l'UserDetailsService sull'oggetto:

authenticator.setUserDetailsService(udService); 

Ma ora Ottengo un'eccezione di credenziali errate quando so che la password fornita è corretta, perché l'ho vista nel debugger nell'oggetto UserDetails impostato in precedenza nel codice.

org.springframework.security.authentication.BadCredentialsException: Bad credenziali a org.springframework.security.authentication.dao.DaoAuthenticationProvider.additionalAuthenticationChecks (DaoAuthenticationProvider.java:87) a org.springframework.security. authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate (AbstractUserDetailsAuthenticationProvider.java:149)

+0

Primavera di sicurezza è open source, si ha il codice sorgente disponibile. Probabilmente stai avendo problemi perché DaoAuthenticationProvider è progettato per essere un bean gestito a molla. – samlewis

risposta

9

ho potuto ottenere l'autenticazione di lavoro mettendo insieme tutte le proprietà definite nella definizione bean molla e se pianificandoli a livello di codice sull'oggetto DaoAuthenticationProvider. Guardando indietro sembra che possa essere stata una domanda sciocca, ma spero che aiuti qualcuno!

codice corretto:

protected void automatedLogin(String username, String password, HttpServletRequest request) { 

     try { 
      // Must be called from request filtered by Spring Security, otherwise SecurityContextHolder is not updated 
      CustomUserDetailsService udService = new CustomUserDetailsService(userDAO, request); 
      CustomMd5PasswordEncoder passEncoder = new CustomMd5PasswordEncoder(); 
      ReflectionSaltSource saltSource = new ReflectionSaltSource(); 
      saltSource.setUserPropertyToUse("salt"); 
      UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password); 
      token.setDetails(new WebAuthenticationDetails(request)); 
      DaoAuthenticationProvider authenticator = new DaoAuthenticationProvider(); 
      authenticator.setUserDetailsService(udService); 
      authenticator.setPasswordEncoder(passEncoder); 
      authenticator.setSaltSource(saltSource); 
      Authentication authentication = authenticator.authenticate(token); 
      SecurityContextHolder.getContext().setAuthentication(authentication); 
     } catch (Exception e) { 
      e.printStackTrace(); 
      SecurityContextHolder.getContext().setAuthentication(null); 
     } 

    } 
+3

Felice di aver trovato una soluzione, ma per essere onesti, non è così che doveva essere usato Spring Security. Stai facendo un sacco di lavoro da solo, che non dovresti. – Akshay

+0

Questo non è il normale utilizzo di Spring Security nell'app. Questa è un'istanza unica in cui è necessario registrare l'utente senza che vengano fornite le credenziali in un modulo. Ogni volta che accederanno tramite il modulo, e il bean di sicurezza primavera farà il lavoro. Avendo spiegato che, se sei quello che ha downvoted la risposta, spero che cambi idea, perché penso che ingiustamente ferisca la mia reputazione su StackOverflow. – rawkfist0215

+0

Resta assicurato amico mio, non ho votato. Non credo che la risposta fosse sbagliata, stavo solo suggerendo che Spring Security non fosse pensata per essere usata in questo modo. E P.S. Giù votando si ridurrebbe la mia reputazione anche su SO ... :) – Akshay

Problemi correlati