springframework/시작하자SpringSecurity

31.CustomAuthenticationSuccessHandler

Jungsoomin :) 2020. 9. 29. 01:21
  1. SimpleUrlAuthenticaionSuccessHandler는 스프링 시큐리에서 지원하는 AuthenticationSuccessHandler 구현체이다.
  2. SimpleUrlAuthenticationSuccessHandler 상속받아 원하는 AuthenticationSuccessHandler 를 만들자.

public void onAuthenticationSuccess(request, response, authentication)

  • 인증에 성공하지 못한 상태에서 로그인페이지에서 다시 인증에 성공하면 사용자가 가려고 했던 자원경로가 담긴 SavedRequest 를 가진 RequestCache 를 가져와 이동시킨다.

사용해야할 객체는 HttpSessionRequestCache 이다.

 

  • 인증 성공 작업이 끝나면 Redirect 시켜줘야하므로 RedirectStrategy 를 사용한다.

사용해야할 객체는 DefaultRedirectStrategy 이다.

@Component
public class CustomAuthenticationHandler extends SimpleUrlAuthenticationSuccessHandler {

    private RequestCache requestCache = new HttpSessionRequestCache();

    private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {

        setDefaultTargetUrl("/");

        SavedRequest savedRequest = requestCache.getRequest(request,response);

        if(savedRequest != null){
            String targetUrl = savedRequest.getRedirectUrl();
            redirectStrategy.sendRedirect(request, response, targetUrl);
        } else {
            redirectStrategy.sendRedirect(request, response, getDefaultTargetUrl());
        }

    }
}

주의 사항

  • 사용자가 인증 이전에 요청한 경로가 없었다면 SavedRequest null 이므로 null 체크를 해주어야한다.
  • redirect 시에 요청정보응답정보를 유지할 수 있게 RedirectStrategy를 사용한다.
  • 인증 실패시 기본 경로를 setDefaultTargetUrl(url) 메서드로 설정, getDefaultTargetUrl(url) 로 가져올 수 있다.
  • AuthenticationSuccessHandler 도 스프링 관리하에 동작하므로 Spring Bean으로 등록한다.

적용

  • SecurityConfig 클래스의 formLogin() 하위 API
  • successHandler() 메서드에 주입받은 CustomAuthenticationSuccessHandler 를 인자로 넘긴다.
@Autowired
    private CustomAuthenticationHandler customAuthenticationHandler;
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/","/users").permitAll()
                .antMatchers("/mypage").hasRole("USER")
                .antMatchers("/messages").hasRole("MANAGER")
                .antMatchers("/config").hasRole("ADMIN")
                .anyRequest().authenticated()

            .and()
                .formLogin()
                .loginPage("/login")
                .defaultSuccessUrl("/")
                .successHandler(customAuthenticationHandler)
                .loginProcessingUrl("/login_proc")
                .permitAll();
    }