[Spring] Interceptor를 통한 API 보안(인증) 적용
Spring Framework에서 API에 대한 보안을 적용하고자 한다. 보통, 스웨거 및 로그인 같은 보안이 필요하지 않은 API를 제외한 다른 API에 대해 보안을 적용한다.
여러가지 방법 중, Interceptor에서 보안(인증)을 적용하는 방법이 있다.
Sep 26, 2024
Spring Framework에서 API에 대한 보안을 적용하고자 한다. 보통, 스웨거 및 로그인 같은 보안이 필요하지 않은 API를 제외한 다른 API에 대해 보안을 적용한다.
여러가지 방법 중, Interceptor에서 보안(인증)을 적용하는 방법이 있다.
왜 인터셉터에서 인증을 적용할까?
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