Spring Security AntPathRequestMatcher 오류 처리

KHS·2023년 8월 3일
0
post-thumbnail

버전 정보

  • Spring Boot 3.0.9
  • Spring Security 6.0.5

패치 노트

https://github.com/spring-projects/spring-security/releases/tag/6.0.5

수정 방안

기존 코드

//권한 확인을 하지 않는 uri
private static final String[] PERMIT_ALL_PATTERNS = new String[] {
  "/v3/api-docs/**",
  "/configuration/**",
  "/swagger*/**",
  "/webjars/**",
  "/swagger-ui/**",
  "/docs",
  "/api/login",
};

@Bean
public SecurityFilterChain securityFilterChain(
  HttpSecurity httpSecurity,
  HandlerMappingIntrospector handlerMappingIntrospector
) throws Exception {
  return httpSecurity
    .authorizeHttpRequests(request ->
      request
        .requestMatchers(PathRequest.toH2Console())
        .permitAll()
        .requestMatchers(PERMIT_ALL_PATTERN)
        .permitAll()
        .requestMatchers(AntPathRequestMatcher.antMatcher("/api/**"))
        .authenticated()
    )
    ...
    build();
}

오류 로그

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.web.SecurityFilterChain]: Factory method 'securityFilterChain' threw exception with message: 
This method cannot decide whether these patterns are Spring MVC patterns or not. If this endpoint is a Spring MVC endpoint, please use requestMatchers(MvcRequestMatcher); otherwise, please use requestMatchers(AntPathRequestMatcher).
        at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:171)
        at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:655)
        ... 24 common frames omitte

수정 코드

//권한 확인을 하지 않는 uri
private static final String[] PERMIT_ALL_PATTERNS = new String[] {
  "/v3/api-docs/**",
  "/configuration/**",
  "/swagger*/**",
  "/webjars/**",
  "/swagger-ui/**",
  "/docs",
  "/api/login",
};

@Bean
public SecurityFilterChain securityFilterChain(
  HttpSecurity httpSecurity,
  HandlerMappingIntrospector handlerMappingIntrospector
) throws Exception {
  return httpSecurity
    .authorizeHttpRequests(request ->
      request
        .requestMatchers(PathRequest.toH2Console())
        .permitAll()
        .requestMatchers( // <== 여기
            Stream
              .of(PERMIT_ALL_PATTERNS)
              .map(AntPathRequestMatcher::antMatcher)
              .toArray(AntPathRequestMatcher[]::new)
          )
        .permitAll()
        .requestMatchers(AntPathRequestMatcher.antMatcher("/api/**"))
        .authenticated()
    )
    ...
    build();
}

기타 사항

  • Spring Boot 3 버전 이상부터 WebSecurityCustomizer Bean은 사용하지 않음
  • WebSecurityCustomizer로 구현된 ignore 처리는 위의 코드대로 permitAll로 대체해야 함
  • 현재 어플리케이션에서 OncePerRequestFilter 등과 같은 필터를 구현해서 사용하고 있다면 해당 상속 클래스에 아래 메소드를 구현해 필터 제외 처리를 해야 함
    @Override
    protected boolean shouldNotFilter(HttpServletRequest request)
      throws ServletException {
      return Stream
        .of(SHOULD_NOT_FILTER_URI_LIST)
        .anyMatch(request.getRequestURI()::startsWith);
    }
profile
Java & Vue ...

3개의 댓글

comment-user-thumbnail
2023년 8월 3일

감사합니다. 이런 정보를 나눠주셔서 좋아요.

답글 달기
comment-user-thumbnail
2023년 9월 16일

덕분에 좋은 내용 잘 보고 갑니다.
정말 감사합니다.

답글 달기
comment-user-thumbnail
2023년 9월 27일

우와.. 이렇게 찾아서 공부해야 함을 다시 느끼면서 반성하게 되네요. 덕분에 문제 잘 해결했습니다. 감사합니다!!

답글 달기