Spring
Interceptor
테니드2
2025. 4. 15. 13:30

Filter와 매우 유사한 형태로 존재 하지만, 차이점은 Spring Context에 등록 된다.
→ 핸들러, 컨트롤러, 메서드 정보 접근 가능
AOP와 유사한 기능을 제공 할 수 있으며,
주로 인증 단계를 처리 하거나, Logging 하는 데에 사용
이를 선/후 처리 함으로써, Service business logic과 분리 시킴
package com.example.demo.annotation;
import java.lang.annotation.*;
import java.lang.reflect.Method;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface Auth {
}
@Auth 검증이 필요한 빈,메소드 등에 사용할 어노테이션을 만든다
package com.example.demo.controller;
import com.example.demo.annotation.Auth;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/private")
@Auth
public class PrivateController {
@GetMapping("/hello")
public String hello(){
return "private hello";
}
}
인터셉터단에서 검증이 필요한 빈이나 메소드등에 @Auth 어노테이션을 추가한다,
package com.example.demo.interceptor;
import com.example.demo.annotation.Auth;
import com.example.demo.exception.AuthException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;
import org.springframework.web.util.UriComponentsBuilder;
import java.net.URI;
@Slf4j
@Component
public class AuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String url = request.getRequestURI();
URI uri = UriComponentsBuilder.fromUriString(url)
.query(request.getQueryString())
.build()
.toUri();
log.info("request url : {}",url);
boolean hasAnnotation = checkAnnotation(handler, Auth.class);
log.info("has annotation : {}",hasAnnotation);
// Auth 권한을 가진 요청에 대해서는 확인 ex) 세션, 쿠키
if(hasAnnotation){
// 권한체크
String query = uri.getQuery();
log.info("query : {}", query);
if(query.equals("name=jun")){
return true;
}
throw new AuthException();
}
return true;
}
private boolean checkAnnotation(Object handler,Class clazz){
// resource javascript, html, etc
if (handler instanceof ResourceHttpRequestHandler){
return true;
}
// annotation
HandlerMethod handlerMethod = (HandlerMethod)handler;
if(null != handlerMethod.getMethodAnnotation(clazz) || null != handlerMethod.getBeanType().getAnnotation(clazz)){
// Auth annotation 있을때 true
return true;
}
return false;
}
}
handler에서 @Auth 어노테이션이 붙는 요청을 확인하여 특정 로직(인증)를 수행하는 예제이다.
package com.example.demo.config;
import com.example.demo.interceptor.AuthInterceptor;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@RequiredArgsConstructor
public class MvcConfig implements WebMvcConfigurer {
private final AuthInterceptor authInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(authInterceptor).addPathPatterns("/api/private/*");
}
}
Configuration에서 WebMvcConfigurer 인터페이스를 구현하고 addInterceptors 메소드에서 registry.addInterceptor 함수 인자에 추가하려는 인터셉터를 추가한다.
addPathPatterns 함수를 이용하여 특정 URI 패턴에만 인터셉터를 적용할 수 있다.