2016-11-26 121 views
0

我創建了以下LogoutSuccessHandlerImpl如何在彈簧安全性中註銷用戶後登錄用戶ID?

public class LogoutSuccessHandlerImpl extends SimpleUrlLogoutSuccessHandler { 

    private final RedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); 

    @Override 
    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { 
     final Long currentUserRoleId = SecurityUtils.getCurrentUserRoleId(); 

     request.getSession().invalidate(); 
     SecurityContextHolder.clearContext(); 

     request.setAttribute("isLoggedOut", "true"); 
     if(currentUserRoleId == UserRole.ADMIN.getId()){ 
      redirectStrategy.sendRedirect(request, response, Constants.ADMIN_LOGIN_URL); 
     } else { 
      redirectStrategy.sendRedirect(request, response, Constants.APPLICANT_LOGIN_URL); 
     } 
    } 
} 

以下是我的安全配置。

@Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http 
      .exceptionHandling() 
       .accessDeniedPage("/accessDenied") 
       .and() 
      .authorizeRequests() 
       .accessDecisionManager(accessDecisionManager) 
       .antMatchers("/").permitAll() 
       .antMatchers("/application/register**").permitAll() 
       .antMatchers("/adminLogin**").permitAll() 
       .antMatchers("/error**").permitAll() 
       .antMatchers("/checkLogin**").permitAll() 
       .anyRequest().fullyAuthenticated() 
       .and() 
      .formLogin() 
       .loginPage("/") 
       .loginProcessingUrl("/checkLogin") 
       .defaultSuccessUrl("/dashboard") 
       .failureHandler(new LoginFailureHandlerImpl()) 
       .usernameParameter("username") 
       .passwordParameter("password") 
       .permitAll() 
       .and() 
      .logout() 
       .logoutUrl("/logout") 
       .logoutSuccessHandler(new LogoutSuccessHandlerImpl()) 
       .deleteCookies("JSESSIONID") 
       .permitAll() 
       .and() 
      .headers() 
       .frameOptions() 
       .disable() 
      .and() 
       .sessionManagement() 
       .maximumSessions(1); 
    } 

下面是我的SecurityUtils。

public static SecurityUser getCurrentUser() { 
     SecurityContext securityContext = SecurityContextHolder.getContext(); 
     Authentication authentication = securityContext.getAuthentication(); 
     if (authentication != null) { 
      if (authentication.getPrincipal() instanceof SecurityUser) { 
       return (SecurityUser) authentication.getPrincipal(); 
      } 
     } 
     throw new IllegalStateException("User not found!"); 
    } 

    public static Long getCurrentUserRoleId() { 
     return SecurityUtils.getCurrentUser().getRoleId(); 
    } 

和我得到的錯誤畢竟是LogoutHandler s的完成執行

java.lang.IllegalStateException: User not found! 
    at com.portal.core.user.security.SecurityUtils.getCurrentUser(SecurityUtils.java:34) 
    at com.portal.core.user.security.SecurityUtils.getCurrentUserRoleId(SecurityUtils.java:38) 
    at com.portal.core.user.security.LogoutSuccessHandlerImpl.onLogoutSuccess(LogoutSuccessHandlerImpl.java:22) 
+0

@ W-S如果if(authentication!= null)不滿足。就在用戶註銷之前,身份驗證不應該爲空。所以異常不應該在那裏。糾正我,如果我錯了。 – ashishjmeshram

回答

0

LogoutSuccessHandler將被調用。這意味着在LogoutSuccessHandlerImpl.onLogoutSuccess中您的代碼被調用時,SecurityContextHolder中不會有任何內容。這是因爲SecurityContextLogoutHandler將被默認註冊。 LogoutSuccessHandlerImpl中的以下行不起作用,因爲它已由SecurityContextLogoutHandler完成。

SecurityContextHolder.clearContext(); 

您可以執行以下操作。

  1. 存儲的用戶ID和角色ID在HTTP會話
  2. 配置您的註銷有logout().invalidateHttpSession(false)
  3. 修改您LogoutSuccessHandlerImpl.onLogoutSuccess從HttpSession中獲取的用戶ID和角色ID而不是SecurityContextHolder
0

authentication始終爲null,因爲在成功註銷後調用LogoutSuccessHandler,請參閱LogoutSuccessHandler

LogoutFilter成功註銷後調用的策略,用於處理重定向或轉發到相應的目標。

您可以實現自定義LogoutHandler獲得成功註銷前用戶的角色ID,請參閱LogoutHandler#logout

參數:

請求 - HTTP請求
響應 - 的HTTP迴應
驗證 - 當前主要細節

相關問題