[Spring] Interceptor를 통한 API 보안(인증) 적용

Spring Framework에서 API에 대한 보안을 적용하고자 한다. 보통, 스웨거 및 로그인 같은 보안이 필요하지 않은 API를 제외한 다른 API에 대해 보안을 적용한다. 여러가지 방법 중, Interceptor에서 보안(인증)을 적용하는 방법이 있다.
Hi's avatar
Sep 26, 2024
[Spring] Interceptor를 통한 API 보안(인증) 적용
 
Spring Framework에서 API에 대한 보안을 적용하고자 한다. 보통, 스웨거 및 로그인 같은 보안이 필요하지 않은 API를 제외한 다른 API에 대해 보안을 적용한다.
여러가지 방법 중, Interceptor에서 보안(인증)을 적용하는 방법이 있다.
 
 
 
왜 인터셉터에서 인증을 적용할까?
notion image
Filter에서는 URI(목적지), Header(어떤 인증을 할 것인지) 등을 알 수 있지만, 해당 요청이 어떤 컨트롤러로 가는지는 Filter에서 알 수 없다.
→ 따라서, Filter에서 인증을 하는 것은 의미가 없다.
 
Interceptor에서는 위 정보를 모두 알 수 있고, 컨트롤러의 권한을 모두 알 수 있다.
→ 따라서, 보통 Interceptor에서 해당 요청을 인증하는 부분을 담당한다.
 
package org.delivery.api.interceptor; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; @Slf4j @RequiredArgsConstructor @Component public class AuthorizationInterceptor implements HandlerInterceptor { }
→ 인터셉터를 상속받은 클래스를 생성한다.
 
package org.delivery.api.interceptor; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; @Slf4j @RequiredArgsConstructor @Component public class AuthorizationInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { log.info("Authorization Interceptor url : {}", request.getRequestURI()); // WEB, Chrome의 경우 GET, POST OPTIONS = pass if (HttpMethod.OPTIONS.matches(request.getMethod())) { return true; } // js, html, png 등 resource를 요청하는 경우 -> pass if (handler instanceof ResourceHttpRequestHandler) { return true; } // TODO: header 검증 return true; } }
→ preHandle 메소드를 구현하고, 로그을 찍어준다.
→ 그리고 웹(특히 크롬)의 경우 GET이나 POST와 같은 API를 요청하기 전에 OPTION이라는 API를 요청해서 해당 API를 지원하는지 체크하는 API를 먼저 보낸다. 이 OPTION API는 그냥 통과하도록 설정해준다.
→ js, html, png 등 리소스를 요청하는 경우도 마찬가지로 그냥 통과시켜준다.
→ 인증 검사는 추후에 하도록 일단 비워둔다.
 
 
이제 인터셉터를 생성했으니, Configuration을 통해 등록하면 된다.
 
 
WebConfig라는 클래스를 생성하고, 아래와 같이 작성한다.
package org.delivery.api.config.web; import java.util.List; import lombok.RequiredArgsConstructor; import org.delivery.api.interceptor.AuthorizationInterceptor; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @RequiredArgsConstructor @Configuration public class WebConfig implements WebMvcConfigurer { private final AuthorizationInterceptor authorizationInterceptor; // 인터셉터 자동 주입 private List<String> OPEN_API = List.of( // 기본 주소 이외에 공개할 주소 "/open-api/**" ); private List<String> DEFAULT_EXCLUDE = List.of( // 기본 주소 (공개) "/", "favicon.ico", // 아이콘 "/error" ); private List<String> SWAGGER = List.of( // 스웨거 주소 "/swagger-ui.html", "/swagger-ui/**", "/v3/api-docs/**" ); @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(authorizationInterceptor) .excludePathPatterns(OPEN_API) .excludePathPatterns(DEFAULT_EXCLUDE) .excludePathPatterns(SWAGGER) ; } }
 
→ @RequiredArgsConstructor를 통해 인터셉터를 자동 주입 시켜준다.
→ 중간에 리스트들은 인터셉터가 그냥 통과시켜줄 수 있도록 excludePathPatterns()에 넣어주는 용도이다.
 
Share article

soultree