1. 개요

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

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

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

2. 맞춤형 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);
    }
}

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

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

우리는 또한 선택적으로 추가 구성을 추가 할 수 있습니다 초기화 () 전과 실행 방법, 구성 () 방법.

다음으로 사용자 정의 구현에 등록하는 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 필터 클래스입니다 . 메시지를 표시하는 데 사용할 로거를 나타내는 두 가지 속성과 오류 코드 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 extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
          //...
          .and()
          .apply(clientErrorLogging());
    }

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

로그하려는 특정 오류 코드 List으로 Bean을 정의 할 수도 있습니다.

@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 에서 찾을 수 있습니다 .