springframework/시작하자SpringSecurity

32.CustomAuthenticationFailureHanlder

Jungsoomin :) 2020. 9. 29. 01:52
  • AuthenticationFailureHanlder 인터페이스에도 스프링 시큐리티가 지원하는 클래스가 있다.
  • SimpleUrlAuthenticationFailureHandler 가 그것이다.
public class CustomAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler 

public void onAuthenticationFailure(request, response, authenticationExcpetion)

 

  • 보통 예외에 대한 분기처리로 나뉜다.
  • UserDetailsService 에서 발생하는 UsernameNotFoundException
  • AuthenticationProvider 에서 발생하는 BadCredentialException 
  • 이외의 예외처리

분기를 나누어 instanceof 연산자로 체크메세지예외내용을 보내게 된다.

@Component
public class CustomAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {

    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {

        String errorMessage = "Invalid Username or Password";

        if(exception instanceof BadCredentialsException)
        {
            errorMessage = "Invalid Password";
        } else if (exception instanceof UsernameNotFoundException) {
            errorMessage = "Invalid Username";
        }

        setDefaultFailureUrl("/login?error=true&exception="+errorMessage);

        super.onAuthenticationFailure(request, response, exception);
    }
}

주의 사항

 

  • setDefaultFailureUrl(url) 로 실패시 이동할 url을 세팅한다. 스프링 시큐리티는 전체의 url을 전부 요청경로로 받기 때문에 허용 설정을 해야한다.
  • 메시지 분기super 클래스에 예외처리를 위임한다.
  • 실패시 요청을 받는 Controller에서 에러메시지를 받아 작업을 거치게 한다.
@GetMapping(value = "/login")
    public String login(@RequestParam(value = "error",required = false) String error,
                        @RequestParam(value = "exception",required = false) String exception, Model model){

        model.addAttribute("error",error);
        model.addAttribute("exception",exception);
        return "user/login/login";
    }

등록

  • SpringSecurity 설정클래스로 이동하여 등록작업을 한다.
  • formLogin() 의 하위 APIfailureHanlder() 주입받은 CustomAuthenticationFailureHandler 를 넘긴다.
@Autowired
    private CustomAuthenticationFailureHandler customAuthenticationFailureHandler;
    
     @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/","/users","user/login/**","/login*").permitAll()
                .antMatchers("/mypage").hasRole("USER")
                .antMatchers("/messages").hasRole("MANAGER")
                .antMatchers("/config").hasRole("ADMIN")
                .anyRequest().authenticated()

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