1. 개요

이 기사에서는 Spring Security Resource Server 에서 생성된 Spring Security 예외를 처리하는 방법을 살펴보겠습니다 . 이를 위해 필요한 모든 구성을 설명하는 실제 예도 사용합니다. 먼저 Spring Security에 대해 간단히 소개하겠습니다.

2. 스프링 시큐리티

Spring Security는 Spring 프로젝트의 일부인 라이브러리입니다. Spring 프로젝트에서 사용자 액세스 제어의 모든 기능을 그룹화하려고 시도합니다 . 액세스 제어를 사용하면 응용 프로그램에서 지정된 사용자 또는 역할 집합이 실행할 수 있는 옵션을 제한할 수 있습니다. 이 방향에서 Spring Security는 비즈니스 로직에 대한 호출을 제어하거나 특정 URL에 대한 HTTP 요청 액세스를 제한합니다 . 이를 염두에 두고 Spring Security에 Security 계층이 어떻게 작동해야 하는지 알려줌으로써 애플리케이션을 구성해야 합니다.

우리의 경우 예외 처리기의 구성에 중점을 둘 것입니다. Spring Security는 이러한 목적을 달성하고 생성된 이벤트를 제어하기 위해 세 가지 다른 인터페이스를 제공합니다.

  • 인증 성공 핸들러
  • 인증 실패 처리기
  • 액세스 거부 처리기

먼저 구성을 자세히 살펴보겠습니다.

3. Security 구성

우선 SecurityFilterChain 빈을 생성해야 하는 구성 클래스가 있습니다. 이것은 애플리케이션의 모든 Security 구성을 관리하는 역할을 합니다. 그래서 여기에서 핸들러를 소개해야 합니다.

한편으로 필요한 구성을 정의합니다.

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http.csrf()
        .disable()
        .httpBasic()
        .disable()
        .authorizeRequests()
        .antMatchers("/login")
        .permitAll()
        .antMatchers("/customError")
        .permitAll()
        .antMatchers("/access-denied")
        .permitAll()
        .antMatchers("/secured")
        .hasRole("ADMIN")
        .anyRequest()
        .authenticated()
        .and()
        .formLogin()
        .failureHandler(authenticationFailureHandler())
        .successHandler(authenticationSuccessHandler())
        .and()
        .exceptionHandling()
        .accessDeniedHandler(accessDeniedHandler())
        .and()
        .logout();
    return http.build();
}

"/login" , "/customError""/access-denied" 와 같은 리디렉션 URL에는 액세스 하기 위해 어떤 유형의 제한도 필요하지 않습니다. 그래서 우리는 그것들에 대해 permitAll() 어노테이션을 달았습니다 .

반면에 처리할 수 있는 예외 유형을 정의하는 Bean을 정의해야 합니다.

@Bean
public AuthenticationFailureHandler authenticationFailureHandler() {
    return new CustomAuthenticationFailureHandler();
} 

@Bean
public AuthenticationSuccessHandler authenticationSuccessHandler() {
   return new CustomAuthenticationSuccessHandler();
}

@Bean
public AccessDeniedHandler accessDeniedHandler() {
   return new CustomAccessDeniedHandler();
}

AuthenticationSuccessHandler 가 행복한 경로를 처리하기 때문에 예외 경우에 대해 나머지 두 개의 빈을 정의합니다. 이 두 핸들러 는 이제 우리가 필요에 맞게 조정하고 구현해야 하는 핸들러 입니다. 따라서 각각의 구현을 진행해 보겠습니다.

4. 인증 실패 핸들러

한편으로는 AuthenticationFailureHandler 인터페이스가 있습니다. 사용자가 로그인에 실패했을 때 발생하는 예외 를 관리하는 역할을 합니다. 이 인터페이스는 핸들러 로직을 커스터마이즈하기 위해 onAuthenticationFailure() 메소드를 제공합니다. 로그인 시도가 실패하면 Spring Security에 의해 호출됩니다 . 이를 염두에 두고 로그인 실패 시 오류 페이지로 리디렉션하도록 예외 처리기를 정의해 보겠습니다.

public class CustomAuthenticationFailureHandler implements AuthenticationFailureHandler {

    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) 
      throws IOException {
        response.sendRedirect("/customError");
    }
}

5. 액세스 거부 처리기

반면에 권한이 없는 사용자가 Security 또는 보호된 페이지에 액세스하려고 하면 Spring Security는 액세스 거부 예외를 throw합니다 . 사용자 정의할 수 있는 Spring Security에서 사용할 수 있는 기본 403 액세스 거부 페이지가 있습니다. 이것은 AccessDeniedHandler 인터페이스 에 의해 관리됩니다 . 또한 사용자를 403 페이지로 리디렉션하기 전에 사용자 정의 논리를 위한 handle() 메서드를 제공합니다 .

public class CustomAccessDeniedHandler implements AccessDeniedHandler {

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException exc) throws IOException {
        response.sendRedirect("/access-denied");
    }
}

6. 결론

이 빠른 기사에서 우리는 Spring Security 예외를 처리하는 방법과 클래스를 생성하고 사용자 정의하여 예외를 제어하는 ​​방법을 배웠습니다 . 또한 설명된 개념을 이해하는 데 도움이 되는 완전한 기능의 예제를 만들었습니다.

기사의 전체 소스 코드는  GitHub에서 사용할 수 있습니다.

Security footer banner