Filtro personalizzato Spring Security (Cambia password)

Sto usando Spring Security per proteggere le richieste HTTP su un sito web. L’utilizzo principale è per proteggere le pagine in modo tale che l’utente venga reindirizzato alla pagina di accesso quando tenta di accedere a tali pagine.

Tuttavia, ho un ulteriore requisito. Nel mio modello, posso segnalare la password di un utente come temporanea in modo tale che, quando accedono correttamente, dovrebbero essere automaticamente costretti a cambiare la loro password. Una volta che la password è cambiata, dovrebbero essere poi inoltrati alla pagina a cui stavano originariamente cercando di accedere.

Qualcuno ha usato Spring Security per questo scopo? Devo creare il mio filtro personalizzato?

Grazie,

Andrea

In Spring Security 3.0 è ansible implementare un AuthenticationSuccessHandler personalizzato.

In questo gestore è ansible redirect un utente con password temporanea alla pagina di modifica della password anziché alla pagina richiesta in origine. Dopo aver cambiato la password, è ansible redirect l’utente alla pagina originariamente richiesta utilizzando SavedRequestAwareAuthenticationSuccessHandler , che è l’implementazione del gestore predefinito.

 public class MyHandler implements AuthenticationSuccessHandler { private AuthenticationSuccessHandler target = new SavedRequestAwareAuthenticationSuccessHandler(); public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication auth) { if (hasTemporaryPassword(auth)) { response.sendRedirect("/changePassword"); } else { target.onAuthenticationSuccess(request, response, auth); } } public void proceed(HttpServletRequest request, HttpServletResponse response, Authentication auth) { target.onAuthenticationSuccess(request, response, auth); } } @Controller("/changePassword") public class ChangePasswordController { @Autowired private MyHandler handler; @RequestMapping(method = POST) public void changePassword(HttpServletRequest request, HttpServletResponse response, @RequestParam(name = "newPassword") String newPassword) { // handle password change ... // proceed to the secured page handler.proceed(request, response, auth); } // form display method, etc ... } 

Un po ‘tardi, ma spero che questo possa aiutare gli altri a trovare questo link. Se si utilizza un UserDetailsService personalizzato, è ansible impostare le credenziali di UserNonExpired su false, ad esempio, per non consentire l’accesso a qualsiasi contenuto protetto finché il campo non viene impostato su true.

In sostanza, quando si ha una scadenza della password, si imposterà un campo nel proprio modello utente (passwordExpired forse), e quando UserDetailsService attira l’utente, UserDetailsService utilizzerà tale valore per impostare credentialsNonExpired.

Quindi, tutto ciò che devi fare è aggiungere qualche configurazione al tuo applicationContext-security.xml per configurare i mapping delle eccezioni di autenticazione. Ciò consentirà di rilevare l’eccezione generata dalle credenziali scadute e forzare l’utente a una pagina di reimpostazione della password. Puoi inoltre catturare account bloccati e disabilitati usando un metodo simile. L’esempio di configurazione è mostrato di seguito:

applicationContext-security.xml

    /login_error /password_expired /locked /disabled        

Quindi assicurati di avere i controller impostati per servire quei collegamenti con il contenuto appropriato.

Sì, l’ho fatto con un filtro ForceChangePasswordFilter. Perché se l’utente digita l’url a mano può ignorare il modulo di cambio password. Con il filtro la richiesta viene sempre intercettata.

Forma di risposta molto utile jyore , era esattamente quello che stavo cercando. Nel caso in cui si stia utilizzando una class personalizzata che implementa UserDetailsService , è ansible farlo come segue insieme alla definizione di bean precedente nel proprio applicationContext.xml . Una cosa è che, in base all’intestazione CML, potrebbe essere necessario utilizzare o anziché o

 import ...... @Service("userService") public class UserDetailsServiceImpl implements UserDetailsService { private static Logger logger = LoggerFactory .getLogger(UserDetailsServiceImpl.class); @Autowired private UserDao userDao; @Override public UserDetails loadUserByUsername( String username ) throws UsernameNotFoundException, DataAccessException , CredentialsExpiredException ,BadCredentialsException , LockedException , DisabledException , UsernameNotFoundException { User user = userDao.getUserByUsername( username ); System.out.println("User Found"); if( user == null ){ // System.out.println("User Not Found"); logger.error( "User Not Found"); throw new UsernameNotFoundException( username + " is not found." ); } if( user.isEnabled() == false ){ // System.out.println("User not enabled"); logger.error( "User not enabled"); throw new DisabledException( "User not enabled" ); } if( user.isLocked() == true ){ //System.out.println("User is Locked"); logger.error( "User is Locked"); throw new LockedException( "User is Locked" ); } if( user.isPasswordExpired() == true ){ // System.out.println("Password Expired"); logger.error( "Password Expired"); throw new CredentialsExpiredException( "Password Expired" ); } return user; } }