2016-04-26 28 views
10

Devo configurare expired-url nella mia applicazione Spring MVC. Qui è il mio sforzo, ma non ha alcun effetto:spring security - expiredUrl non funziona

@Override 
protected void configure(HttpSecurity http) throws Exception { 
    http 
     .addFilterBefore(adminAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class) 
     .addFilterBefore(customerAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class) 
     .csrf() 
      .disable() 
     .authorizeRequests() 
      .antMatchers("...", "...", "...").permitAll() 
      .anyRequest().authenticated() 
     .and() 
      .formLogin() 
       .loginPage("/admin/login") 
     .and() 
      .logout() 
       .addLogoutHandler(customLogoutHandler()) 
       .logoutSuccessHandler(customLogoutSuccessHandler()) 
       .logoutUrl("/logout") 
     .deleteCookies("remove") 
     .invalidateHttpSession(true) 
      .permitAll() 
     .and() 
     .sessionManagement() 
      .maximumSessions(1) 
      .expiredUrl("/expired"); 

} 

questo non deve alcun effetto e quando i tempi di sessione dell'utente fuori, la primavera non lo reindirizzano a /expired URL e solo lui reindirizza al /admin/login URL.

Aggiornamento:

ho provato suggerito soluzioni nei commenti e risposta, ma non ha visto alcun effetto. Inoltre ho rimosso addLogoutHandler(), logoutSuccessHandler() e due addFilterBefore() all'inizio del metodo, ma non funzionante.

Inoltre ho provato un'altra soluzione in questo modo:

@Override 
protected void configure(HttpSecurity http) throws Exception { 
    http 
     .addFilterBefore(sessionManagementFilter(), SessionManagementFilter.class) 
     .csrf() 
      .disable() 
     .authorizeRequests() 
      .antMatchers("...", "...", "...").permitAll() 
      .anyRequest().authenticated() 
     .and() 
      .formLogin() 
       .loginPage("/admin/login") 
     .and() 
      .logout() 
       .logoutUrl("/logout") 
     .deleteCookies("remove") 
     .invalidateHttpSession(true) 
      .permitAll(); 
} 

@Bean 
public SessionManagementFilter sessionManagementFilter() { 
    SessionManagementFilter sessionManagementFilter = new SessionManagementFilter(httpSessionSecurityContextRepository()); 
    sessionManagementFilter.setInvalidSessionStrategy(simpleRedirectInvalidSessionStrategy()); 
    return sessionManagementFilter; 
} 

@Bean 
public SimpleRedirectInvalidSessionStrategy simpleRedirectInvalidSessionStrategy() { 
    SimpleRedirectInvalidSessionStrategy simpleRedirectInvalidSessionStrategy = new SimpleRedirectInvalidSessionStrategy("/expired"); 
    return simpleRedirectInvalidSessionStrategy; 
} 

@Bean 
public HttpSessionSecurityContextRepository httpSessionSecurityContextRepository(){ 
    HttpSessionSecurityContextRepository httpSessionSecurityContextRepository = new HttpSessionSecurityContextRepository(); 
    return httpSessionSecurityContextRepository; 
} 

Qualcuno potrebbe aiutarmi a risolvere questo problema?

+3

@hamed, okay .. immagino che non si dispone dell'autorizzazione necessaria per accedere '/ url expired' (so che questo è imbarazzante dal momento che si tratta di un URL per la scadenza! maneggiando), quindi spring reindirizza alla pagina di accesso anche per accedere alla pagina scaduta. Non c'è niente di doloroso nel provare .. Basta provare ad aggiungere '.antMatchers ("/expired "," ... ", ...). allowAll() ', quindi controlla se ora sei reindirizzato correttamente alla pagina scaduta o ancora la pagina di accesso. Fammi sapere se non funziona .. –

risposta

8

ho provato la soluzione Ali Dehghani 's (nei commenti) in questo modo:

.sessionManagement().maximumSessions(1).and().invalidSessionUrl("/expired"); 

e come il Coder detto, aggiungere "/expired" negli URL consentiti e il problema risolto. Grazie a tutti coloro che hanno prestato attenzione al mio problema, in particolare Ali Dehghani e Il codificatore, per i loro utili commenti.

0

Idealmente il tuo UX dovrebbe semplicemente reindirizzare l'utente alla pagina di accesso. Immagino tu veda il requisito di avere una pagina dedicata/scaduta a causa di Spring MVC - change security settings dynamically dove hai informato sulla tua necessità di avere maschere di accesso separate. Se la soluzione alternativa (quella che ho descritto nella mia risposta sull'altra domanda) funziona per te, potresti forse abbandonare la tua esigenza di avere una pagina dedicata/scaduta e reindirizzare l'utente alla pagina di login corretta usando direttamente il numero di soluzione (2). Che ne dici di quello?

Tuttavia, per rispondere alla tua domanda in corso ... Non sono sicuro se funziona ma fare un tentativo e cambiare il codice

 //... 
     .sessionManagement() 
     .maximumSessions(1) 
     .expiredUrl("/expired"); 
    } 

a

 //... 
     .sessionManagement().sessionFixation().newSession().maximumSessions(1) 
     .expiredUrl("/expired") 
     .sessionRegistry(sessionRegistry()); 
    } 

    @Bean 
    public SessionRegistry sessionRegistry() { 
     SessionRegistry sessionRegistry = new SessionRegistryImpl(); 
     return sessionRegistry; 
    } 

Nel caso in cui non funziona, potresti quindi pubblicare il codice del tuo customLogoutHandler() e customLogoutSuccessHandler()? Stai utilizzando Spring MVC al di fuori di Spring Boot, corretto?

+0

Ho rimosso 'customLogoutHandler()' e 'customLogoutSuccessHandler()' e ho provato la tua soluzione, ma non ho visto alcun effetto. Ancora quando scade la sessione, molla mi reindirizza all'URL di accesso. – hamed

5

ConcurrentSessionFilter reindirizzerà al expiredUrl, se l'ID valid sessione è contrassegnato come scaduto nel SessionRegistry, vedi Spring Security reference:

- scaduto-url L'URL di un utente verrà reindirizzato a se tentano di usare una sessione che è stata "scaduta" dal controller di sessione simultaneo perché l'utente ha superato il numero di sessioni consentite e ha effettuato nuovamente l'accesso altrove. Dovrebbe essere impostato a meno che non sia impostato exception-if-maximum-exceeded. Se non viene fornito alcun valore, un messaggio di scadenza verrà semplicemente riportato direttamente alla risposta.

SessionManagementFilter reindirizzerà al invalidSessionUrl, se l'ID di sessione non è valid (timeout o ID sbagliato), vedere Spring Security reference:

Se l'utente non è attualmente autenticato, il filtro sarà verificare se un invalido è stato richiesto un ID di sessione (a causa di un timeout, ad esempio) e invocherà lo InvalidSessionStrategy configurato, se ne è stato impostato uno.Il comportamento più comune consiste nel reindirizzare a un URL fisso e questo è incapsulato nell'implementazione standard SimpleRedirectInvalidSessionStrategy. Quest'ultimo viene anche utilizzato quando si configura un URL di sessione non valido attraverso lo spazio dei nomi, come descritto in precedenza.

Entrambi gli URL (expiredUrl, invalidSessionUrl) devono essere configurati come permitAll().

BTW: Se si desidera utilizzare Concurrent Session Control con maximumSessions si deve aggiungere HttpSessionEventPublisher al vostro web.xml:

Sessione Simultanea di controllo

Se si desidera inserire i vincoli sulla capacità di un singolo utente a accedi alla tua applicazione, Spring Security supporta questo fuori dalla scatola con le seguenti semplici aggiunte. In primo luogo è necessario aggiungere il seguente ascoltatore al file web.xml per mantenere Primavera di sicurezza aggiornato sugli eventi del ciclo di vita di sessione:

<listener> 
    <listener-class> 
      org.springframework.security.web.session.HttpSessionEventPublisher 
    </listener-class> 
</listener> 
0

Se si utilizza UserDetails e UserDetailsService, allora dovrebbe essere perché la classe di implementazione UserDetails non ha alcun metodo Override hashCode() ed equals (Object obj). Questa è la mia classe di implementazione per UserDetails:

public class MyUser implements UserDetails { 
    private String username; 

    private String password; 

    public void setUsername(String username) { 
     this.username = username; 
    } 

    public void setPassword(String password) { 
     this.password = password; 
    } 

    @Override 
    public Collection<? extends GrantedAuthority> getAuthorities() { 
     return null; 
    } 

    @Override 
    public String getPassword() { 
     return null; 
    } 

    @Override 
    public String getUsername() { 
     return null; 
    } 

    @Override 
    public boolean isAccountNonExpired() { 
     return false; 
    } 

    @Override 
    public boolean isAccountNonLocked() { 
     return false; 
    } 

    @Override 
    public boolean isCredentialsNonExpired() { 
     return false; 
    } 

    @Override 
    public boolean isEnabled() { 
     return false; 
    } 

    @Override 
    public int hashCode() { 
     return username.hashCode(); 
    } 

    @Override 
    public boolean equals(Object obj) { 
     return this.toString().equals(obj.toString()); 
    } 
} 
Problemi correlati