[SPRING] @ControllerAdvice로 간단한 서블릿 필터 작동
SPRING@ControllerAdvice로 간단한 서블릿 필터 작동
요청에 정적 키 (사용자 인증 없음)가있는 특수 헤더가 엔드 포인트를 보호하기 위해 포함되어 있는지 확인하는 간단한 필터가 있습니다. 아이디어는 키가 일치하지 않으면 AccessForbiddenException을 던지고 @ControllerAdvice로 주석이 달린 클래스의 응답에 매핑됩니다. 그러나 나는 그것을 작동시킬 수 없다. 내 @ExceptionHandler가 호출되지 않았습니다.
ClientKeyFilter
import org.springframework.beans.factory.annotation.Value
import org.springframework.stereotype.Controller
import javax.servlet.*
import javax.servlet.http.HttpServletRequest
@Controller //I know that @Component might be here
public class ClientKeyFilter implements Filter {
@Value('${CLIENT_KEY}')
String clientKey
public void init(FilterConfig filterConfig) {}
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
req = (HttpServletRequest) req
def reqClientKey = req.getHeader('Client-Key')
if (!clientKey.equals(reqClientKey)) {
throw new AccessForbiddenException('Invalid API key')
}
chain.doFilter(req, res)
}
public void destroy() {}
}
액세스 금지
public class AccessForbiddenException extends RuntimeException {
AccessForbiddenException(String message) {
super(message)
}
}
ExceptionController
@ControllerAdvice
class ExceptionController {
static final Logger logger = LoggerFactory.getLogger(ExceptionController)
@ExceptionHandler(AccessForbiddenException)
public ResponseEntity handleException(HttpServletRequest request, AccessForbiddenException e) {
logger.error('Caught exception.', e)
return new ResponseEntity<>(e.getMessage(), I_AM_A_TEAPOT)
}
}
내가 틀렸어? 간단한 서블릿 필터가 스프링 부트의 예외 매핑과 함께 작동 할 수 있습니까?
해결법
-
==============================
1.java 서블릿 스펙에 지정된대로 서블릿이 호출되기 전에 항상 필터가 실행됩니다. 이제 @ControllerAdvice는 DispatcherServlet 내에서 실행되는 컨트롤러에만 유용합니다. 따라서 필터를 사용하고 @ControllerAdvice 또는이 경우 @ExceptionHandler가 호출 될 것으로 예상됩니다.
java 서블릿 스펙에 지정된대로 서블릿이 호출되기 전에 항상 필터가 실행됩니다. 이제 @ControllerAdvice는 DispatcherServlet 내에서 실행되는 컨트롤러에만 유용합니다. 따라서 필터를 사용하고 @ControllerAdvice 또는이 경우 @ExceptionHandler가 호출 될 것으로 예상됩니다.
JSON 응답을 작성하기 위해 필터에 동일한 논리를 입력하거나 필터 대신이 검사를 수행하는 HandlerInterceptor를 사용해야합니다. 가장 쉬운 방법은 HandlerInterceptorAdapter를 확장하고 preHandle 메서드를 재정의하고 구현 한 다음 필터의 논리를 해당 메서드에 넣는 것입니다.
public class ClientKeyInterceptor extends HandlerInterceptorAdapter { @Value('${CLIENT_KEY}') String clientKey @Override public boolean preHandle(ServletRequest req, ServletResponse res, Object handler) { String reqClientKey = req.getHeader('Client-Key') if (!clientKey.equals(reqClientKey)) { throw new AccessForbiddenException('Invalid API key') } return true; } }
-
==============================
2.@ControllerAdvice는 일부 컨트롤러에서 예외가 발생하면 호출되기 때문에 사용할 수 없지만 ClientKeyFilter는 @Controller가 아닙니다.
@ControllerAdvice는 일부 컨트롤러에서 예외가 발생하면 호출되기 때문에 사용할 수 없지만 ClientKeyFilter는 @Controller가 아닙니다.
@Controller 주석을 @Component로 바꾸고 다음과 같이 응답 본문과 상태를 설정해야합니다.
@Component public class ClientKeyFilter implements Filter { @Value('${CLIENT_KEY}') String clientKey public void init(FilterConfig filterConfig) { } public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; String reqClientKey = request.getHeader("Client-Key"); if (!clientKey.equals(reqClientKey)) { response.sendError(HttpServletResponse.SC_FORBIDDEN, "Invalid API key"); return; } chain.doFilter(req, res); } public void destroy() { } }
from https://stackoverflow.com/questions/30335157/make-simple-servlet-filter-work-with-controlleradvice by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] RESTful Spring MVC 컨트롤러에서 유효성 검사 오류 및 예외를 처리하는 방법은 무엇입니까? (0) | 2019.08.14 |
---|---|
[SPRING] 퍼즐 모듈을 사용하여 jdk9로 스프링 부트 실행 (0) | 2019.08.14 |
[SPRING] Spring Webflux,`ServerResponse` 테스트 (0) | 2019.08.14 |
[SPRING] 직렬화에서 JPA Lazy Fetching을 트리거하는 Jackson (0) | 2019.08.13 |
[SPRING] 경로 변수를 기반으로하는 스프링 보안 권한 (0) | 2019.08.13 |