Spring Interceptor resource, preflight

minseok·2023년 10월 20일
0

문제

Spring Security를 사용하지 않고 Interceptor를 사용하여 인증 로직 처리를 한다.
Broswer에서 Backend server로 날리는 preflight 요청이 Custom Interceptor에서 터진다. -> 요청이 처리되지 않음
결론 : preflight 요청이 정상적으로 응답할 수 있도록 하자





설명

모든 Request가 나의 Custom Interceptor의 아래 메서드를 호출한다.
인증용 인터셉터이다.
호출되는 Method의 annotation에 RequireAuth가 있는 경우 토큰 인증을 하는 로직을 포함한다.

하지만 Swagger 요청이나 Preflight의 경우 preHandle(..., Object handler)에서 handler 파라미터에 HadnlerMethod로 캐스팅할 수없는 타입이 들어온다.
이러한 경우 ClassCastException을 던진다.



해결 방법

1. addPathPatterns()를 사용한다.
특정 PathPattern에 등록된 Interceptor만 사용한다.
이렇게 최대한 Framework의 가이드 라인을 따라가는 것이 좋다.



2. HttpMethod 확인하기
작은 규모의 애플리케이션에서는 적당하다고 생각한다.
하지만 규모가 커지고 Interceptor의 구현체가 가지는 책임이 명확해지면 슬쩍 넣기에는 애매할 것 같다.

if(request.getMethod().equals("OPTIONS")) {
	return true;
}



3. Custom Interceptor에 preHandle()의 인자로 넘어온 Object handler Type을 확인한다.
2번처럼 동일한 단점을 가지는 것 같다.
만약 이런 방식을 사용한다면 blacklist의 개념보다는 whitelist의 개념을 사용하는게 명확하다.

예로 들자면 조건이 사과 형태의 요청이 아닌 것만 책임진다. 보다는 포도 형태의 요청만 책임진다. 이런 것





handler? interceptor? handlerMethod?

handler와 handler Interceptor는 handlerExcutionChain에 묶인다.

Chain의 Constructor, Method를 보면 핸들러를 생성자에서 1번 받고 나머지는 모두 인터셉터를 추가한다.
대충보면 핸들러 1개에 0개 이상의 인터셉터를 연결하겠구나 싶다.


Handler

DispatcherServlet에서 HandlerMapping에 request 기준으로 얻어오는 객체이다.
개발자는 Interceptor에서 Parameter로 받아 여러 로직에 사용할 수 있다.

1. RequestMappingHandlerMapping으로 찾은 경우
handler가 HandlerMethod 타입을 참조하고 있다.
@RequsetMapping 같은 API를 요청하면 해당 Mapping이 찾아준다.

2. SimpleUrlHandlerMapping으로 찾은 경우
handler가 ResourceHttpRequestHandler 타입을 참조하고 있다.

ResourceHttpRequestHandler가 HandlerMethod와 상속구조는 아니다.

Interceptor List

요청이 올 때마다 AbstractHandlerMapping에서 동적으로 Chain에 넣어서 보내준다.
순서는 먼저 handler를 선택한 뒤 Interceptor List가 추가된다.
(interceptor 선택에는 WebMVConfigurer의 includePattern, excludePattern를 참조한다.)

여러 handler mapping(simpleUrl..., RequsetMapping..., ...)을 순회하면서
Handler를 찾고 그후에 mapping.getHandler(request)에서
완전한 HandlerExecutionChain을 만들어준다.

이제 adapter.supports(handler)가 true이면 마무리가 된다.

profile
즐겁게 개발하기

0개의 댓글