2016-04-26 146 views
10

我需要在我的Spring MVC應用程序中配置expired-url。這是我的工作,但沒有效果:spring security - expiredUrl無法正常工作

@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"); 

} 

這不會有任何效果,當用戶的會話超時,春天不會他重定向到URL /expired,只是重定向他/admin/login網址。

更新:

我想提出的意見和答案的解決方案,但沒有看到任何效果。在方法開始時我也刪除了addLogoutHandler(),logoutSuccessHandler()和兩個addFilterBefore(),但是沒有工作。

我也試過這樣另一種解決方案:

@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; 
} 

誰能幫我解決這個問題呢?

+3

,好吧..我想你沒有訪問'/ expired' URL(我知道這是尷尬的,因爲這是一個過期URL必要的權限!處理),所以春季重定向你登錄頁面,甚至訪問過期的頁面..沒有痛苦嘗試..只要嘗試添加'.antMatchers(「/ expired」,「...」,...)。permitAll ()',然後檢查現在是否已成功重定向到過期頁面或仍然是登錄頁面。讓我知道如果它不工作.. –

回答

8

我試過阿里德赫加尼的這樣的解決方案(在評論):

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

而作爲編碼器說,在允許的網址添加"/expired"和問題就解決了。謝謝大家關注我的問題,尤其是阿里德赫尼尼編碼器,他們的有用的意見。

0

理想情況下,您的UX應該簡單地將用戶重定向回登錄頁面。我想你會看到有一個專用/過期頁面的要求,因爲Spring MVC - change security settings dynamically你通知你需要分開登錄掩碼。如果解決方法(我在您的其他問題的答案中描述的解決方案)適用於您,則可以放棄使用專用/過期頁面的要求,並使用解決方案編號直接將用戶重定向到正確的登錄頁面2)。那個怎麼樣?

然而,要回答你的當前問題...... 我不知道,如果它的工作原理,但給它一個嘗試和改變你的代碼

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

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

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

如果它不起作用,您可以發佈您的customLogoutHandler()customLogoutSuccessHandler()的代碼嗎?你在Spring Boot之外使用Spring MVC,對嗎?

+0

我刪除了'customLogoutHandler()'和'customLogoutSuccessHandler()',並試過你的解決方案,但沒有看到任何效果。當會話超時後,Spring會將我重定向到登錄網址。 – hamed

5

ConcurrentSessionFilter會重定向到expiredUrl,如果valid會話ID被標記爲SessionRegistry過期,請Spring Security reference

- 過期的URL用戶會被重定向到如果他們試圖使用的URL由併發會話控制器「已過期」的會話,因爲用戶已超出允許的會話數量並在別處再次登錄。除非設置了exception-if-maximum-exceeded,否則應該設置。如果沒有提供任何值,過期消息將直接寫回響應。

SessionManagementFilter會重定向到invalidSessionUrl,如果會話ID是不valid(超時或錯誤的ID),見Spring Security reference

如果用戶目前未被驗證時,過濾器會檢查是否無效會話ID已被請求(例如由於超時),並且將調用已配置的InvalidSessionStrategy(如果已設置)。最常見的行爲就是重定向到一個固定的URL,並將其封裝在標準實現SimpleRedirectInvalidSessionStrategy中。如前所述,在通過命名空間配置無效會話URL時也使用後者。

兩個網址(expiredUrlinvalidSessionUrl)必須被配置爲permitAll()

順便說一句:如果你想使用Concurrent Session ControlmaximumSessions必須添加HttpSessionEventPublisherweb.xml

同步會話控制

如果你想放置在單個用戶的能力限制登錄到您的應用程序,Spring Security支持這個開箱即用的以下簡單添加。首先,你需要下面的監聽器添加到您的web.xml文件裏,讓Spring Security的更新session生存週期事件:

​​
0

如果您使用UserDetailsUserDetailsService那麼它應該是因爲您的UserDetails實現類沒有覆蓋hashCode()和equals(Object obj)方法。這是我的UserDetails實現類:@hamed

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()); 
    } 
}