1. 개요

Spring Security Java 구성 지원은 강력한 유창한 API를 제공하여 애플리케이션에 대한 Security 매핑 및 규칙을 정의합니다.

이 빠른 기사에서는 한 단계 더 나아가 실제로 사용자 지정 구성자를 정의하는 방법을 살펴보겠습니다. 이것은 표준 Security 구성에 사용자 정의 논리를 도입하는 고급스럽고 유연한 방법입니다.

여기의 빠른 예에서는 주어진 오류 상태 코드 List에 따라 인증된 사용자에 대한 오류를 기록하는 기능을 추가합니다.

2. Custom형 SecurityConfigurer

구성자를 정의하기 시작하려면 먼저 AbstractHttpConfigurer 클래스 를 확장해야 합니다 .

public class ClientErrorLoggingConfigurer 
  extends AbstractHttpConfigurer<ClientErrorLoggingConfigurer, HttpSecurity> {

    private List<HttpStatus> errorCodes;
    
    // standard constructors
    
    @Override
    public void init(HttpSecurity http) throws Exception {
        // initialization code
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
       http.addFilterAfter(
         new ClientErrorLoggingFilter(errorCodes), 
         FilterSecurityInterceptor.class);
    }
}

여기서 재정의해야 하는 주요 메서드는 이 구성자가 적용할 Security 구성을 포함하는 configure() 메서드 입니다.

이 예에서는 마지막 Spring Security 필터 다음에 새 필터를 등록했습니다. 또한 응답 상태 오류 코드를 기록할 예정이므로 기록할 오류 코드를 제어하는 ​​데 사용할 수 있는 errorCodes List 속성을 추가했습니다.

또한 configure ( ) 메서드보다 먼저 실행되는 init() 메서드 에 추가 구성을 선택적으로 추가할 수도 있습니다 .

다음으로 사용자 정의 구현에 등록한 Spring Security 필터 클래스를 정의해 보겠습니다.

public class ClientErrorLoggingFilter extends GenericFilterBean {

    private static final Logger logger = LogManager.getLogger(
      ClientErrorLoggingFilter.class);
    private List<HttpStatus> errorCodes;

    // standard constructor

    @Override
    public void doFilter(
      ServletRequest request, 
      ServletResponse response, 
      FilterChain chain) 
      throws IOException, ServletException {
        //...

        chain.doFilter(request, response);
    }
}

이것은 GenericFilterBean 을 확장하고 doFilter() 메소드 를 재정의 하는 표준 Spring 필터 클래스입니다. 메시지를 표시하는 데 사용할 로거와 errorCode List나타내는 두 가지 속성이 있습니다 .

doFilter() 메서드 를 자세히 살펴보겠습니다 .

Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth == null) {
    chain.doFilter(request, response);
    return;
}
int status = ((HttpServletResponse) response).getStatus();
if (status < 400 || status >= 500) {
    chain.doFilter(request, response);
    return;
}
if (errorCodes == null) {
    logger.debug("User " + auth.getName() + " encountered error " + status);
} else {
    if (errorCodes.stream().anyMatch(s -> s.value() == status)) {
        logger.debug("User " + auth.getName() + " encountered error " + status);
    }
}

상태 코드가 400에서 500 사이를 의미하는 클라이언트 오류 상태 코드인 경우 errorCodes List을 확인합니다.

이것이 비어 있으면 클라이언트 오류 상태 코드가 표시됩니다. 그렇지 않으면 먼저 오류 코드가 주어진 상태 코드 List 의 일부인지 확인합니다.

3. 사용자 지정 구성기 사용

이제 사용자 정의 API 가 있으므로 bean을 정의한 다음 HttpSecurity 의 apply() 메소드사용하여 이를 Spring Security 구성에 추가할 수 있습니다 .

@Configuration
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            //...
            .and()
            .apply(clientErrorLogging());
        return http.build();
    }

    @Bean
    public ClientErrorLoggingConfigurer clientErrorLogging() {
        return new ClientErrorLoggingConfigurer();
    }

}

또한 기록하려는 특정 오류 코드 List으로 빈을 정의할 수 있습니다.

@Bean
public ClientErrorLoggingConfigurer clientErrorLogging() {
    return new ClientErrorLoggingConfigurer(Arrays.asList(HttpStatus.NOT_FOUND)) ;
}

그리고 그게 다야! 이제 Security 구성에 사용자 지정 필터가 포함되고 로그 메시지가 표시됩니다.

기본적으로 사용자 정의 구성자를 추가하려면 META-INF/spring.factories 파일을 사용할 수 있습니다.

org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer = com.baeldung.dsl.ClientErrorLoggingConfigurer

수동으로 비활성화하려면 disable() 메서드를 사용할 수 있습니다.

//...
.apply(clientErrorLogging()).disable();

4. 결론

이 빠른 사용방법(예제)에서는 Spring Security 구성 지원의 고급 기능에 중점을 두었습니다. 우리는 자체 사용자 정의 SecurityConfigurer 를 정의하는 방법을 보았습니다 .

항상 그렇듯이 예제의 전체 소스 코드는 GitHub 에서 찾을 수 있습니다 .

Security footer banner