2016-11-26 7 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)が満たされない場合。ユーザーがログアウトする直前に、認証をnullにすることはできません。だから例外はそこにあるべきではない。私が間違っているなら、私を訂正してください。 – ashishjmeshram

答えて

0

LogoutSuccessHandlerが呼び出されますされています。これは、SecurityContextHolderに何もないときにあなたのコードLogoutSuccessHandlerImpl.onLogoutSuccessが呼び出されることを意味します。これは、デフォルトでSecurityContextLogoutHandlerが登録されるためです。 LogoutSuccessHandlerImplの次の行は、すでにSecurityContextLogoutHandlerによって行われているため、何の効果もありません。

SecurityContextHolder.clearContext(); 

以下が可能です。

  1. ストアHTTPセッション中にユーザーIDと役割同上
  2. logout().invalidateHttpSession(false)
  3. ではなくSecurityContextHolder
0
でのHttpSessionからユーザーIDおよびロールIDを得るためにあなたの LogoutSuccessHandlerImpl.onLogoutSuccessを変更持っているあなたのログアウトを設定します

authenticationは、ログアウトに成功した後にLogoutSuccessHandlerが呼び出されるため、常にnullです。LogoutSuccessHandler

適切な宛先へのリダイレクトまたは転送を処理するために、LogoutFilterによってログアウトが成功した後に呼び出される戦略。

パラメータ:: - HTTPリクエスト
応答 - HTTP

要求

あなたは成功したログアウトする前に、ユーザーの役割のIDを取得するためのカスタム LogoutHandlerを実装することができ

は、LogoutHandler#logoutを参照してください応答
認証 - 現在のプリンシパルの詳細

関連する問題