인프런 커뮤니티 질문&답변

literate_t님의 프로필 이미지
literate_t

작성한 질문수

스프링 시큐리티 OAuth2

RSA 검증 기능 구현 - JwtAuthorizationRsaFilter

JwtAuthorizationFilter에 대한 질문입니다!

작성

·

162

0

안녕하세요.

테스트를 하다 보니까 (결과적으론 저의 실수인데요) 토큰을 검증하는 로직이 두 번 실행되는 겁니다. Mac 방식과 Rsa 방식 둘 다요. OAuth2ResourceServer에서 분명 addFilterBefore()에서는 하나의 필터만 넣어주었는데 말이죠.

궁금해서 찾아보니 OAuth2ResourceServer에서 Mac방식과 RSA 방식 모두를 Bean으로 만들어서 그런 거였습니다. addFilter에 넣은 커스텀 필터만 동작하는 줄 알았지만, OncePerRequestFilter를 상속하면 빈으로 만드는 것만으로도 필터 목록에 추가되더라고요. 확인해 보니 가장 마지막에 추가되는 것 같습니다. 여기서 질문입니다!

addFilterBefore() 등의 함수로 커스텀 필터의 위치를 지정하하면서, 설정에서 MAC과 RSA의 bean을 둘 다 살리면서 동작하는 방법은 없는 걸까요~? GenericFilterBean을 상속하게 해서 구현해도 addFilter 없이도 동작을 하니까 아래처럼 두 Bean 모두 살아있으면 검증을 두 번 하게 되네요.

  @Bean
  public JwtAuthorizationMacFilter jwtAuthorizationMacFilter(OctetSequenceKey octetSequenceKey)
      throws JOSEException {
    return new JwtAuthorizationMacFilter(new MACVerifier(octetSequenceKey.toSecretKey()));
  }

  @Bean
  public JwtAuthorizationRsaFilter jwtAuthorizationRsaFilter(RSAKey rsakey) throws JOSEException {
    return new JwtAuthorizationRsaFilter(new RSASSAVerifier(rsakey.toRSAPublicKey()));
  }

답변 1

0

안녕하세요, 인프런 AI 인턴입니다.
님의 질문에 답변드립니다.

JwtAuthorizationFilter가 두 번 실행되는 문제는 하나의 필터만 명시하는 것이 아니라, 두 가지 방식의 JwtAuthorizationFilter가 모두 스프링 시큐리티 필터 체인에 등록되어 있기 때문에 발생합니다. 스프링 시큐리티의 필터 체인은 OncePerRequestFilter를 상속한 필터에 대해 해당 필터가 빈으로 등록되어 있는 경우 자동으로 필터 체인에 포함시키기 때문입니다.

addFilterBefore() 등의 함수로 특정한 위치에 커스텀 필터를 지정하는 것은 가능하지만, 두 방식의 필터를 동시에 유지하면서 중복 실행을 방지하려면 별도의 로직을 구현해야 합니다. 예를 들어, 하나의 필터에서 조건에 따라 MAC 방식과 RSA 방식 중 하나를 선택하여 실행하게 하는 방법이 있을 수 있습니다.

예를 들어 아래처럼 단일 필터에서 내부적으로 조건에 따라 검증 방식을 결정하도록 구현할 수 있습니다.

@Bean
public Filter registrationFilter() {
  return new OncePerRequestFilter() {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
        throws ServletException, IOException {
      
      try {
        // MAC 검증 로직 수행
        // RSA 검증 로직 수행
        // 어떤 검증 방식을 사용할지 결정하는 로직
        // ex) 토큰 형식을 확인하고 MAC이면 MAC 검증, RSA면 RSA 검증을 수행
      } catch (AuthenticationException e) {
        // 검증 실패 처리
        return;
      }

      // 계속해서 필터 체인을 수행
      filterChain.doFilter(request, response);
    }
  }
}

해당 로직을 구현하면 하나의 필터에서 두 가지 방식의 토큰 검증 로직을 분기 처리할 수 있으며, 중복 실행 문제를 해결할 수 있습니다.

예시에 나와 있는 것처럼 JwtAuthorizationMacFilterJwtAuthorizationRsaFilter 두 컴포넌트 모두를 빈으로 등록하는 대신에, 하나의 빈으로 통합하여 그 안에서 조건에 따라 다른 검증 로직을 실행하는 방식으로 변경해야 할 것입니다.

literate_t님의 프로필 이미지
literate_t

작성한 질문수

질문하기