필터는 모든 요청에 대해 동작한다. 특정 url에서만 필터가 동작하도록 하기 위해 White List를 리스트 형태로 만들었다.
다만 아래와 같은 상황에서 어떻게 구현할지 고민이 되었다.
/restaurants
는 통과, /restaurants/{restaurant-id}/waitings
는 통과하면 안될 때 필터 조건을 어떻게 줄 수 있을까?
private static final List<String> WHITELIST_URLS = Arrays.asList(
"/login",
"/logout",
"/signup",
"/static",
"/css",
"/js",
"/owner"
);
private static final List<String> BLACKLIST_URLS = Arrays.asList(
"/reviews/create",
"/scraps",
"/waiting",
"/reservation"
);
@Override
protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
String requestURI = request.getRequestURI();
return WHITELIST_URLS.stream().anyMatch(requestURI::startsWith);
}
if (requestURI.startsWith("/restaurants") && !isBlacklisted(requestURI)) {
chain.doFilter(request, response);
return;
}
BasicAuthenticationFilter는 OncePerRequestFilter를 상속받는다. OncePerRequestFilter는 아래와 같은 메서드를 재정의하여 사용할 수 있다.
*protected boolean* shouldNotFilter(*HttpServletRequest* request) *throws* ServletException {
*return false*;
}
아래와 같은 화이트리스트가 있다고 가정하자.
private static final List<String> WHITELIST_URLS = Arrays.asList(
"/owner/login",
"/owner/signup",
"/templates",
"/static",
"/css",
"/js"
);
기존에는 아래와 같은 메서드를 만들어 WHITELIST_URLS로 시작하는 경로는 모두 필터를 통과시켰다.
private boolean isWhitelisted(String requestURI) {
return WHITELIST_URLS.stream().anyMatch(url -> requestURI.startsWith(url));
}
doFilterInternal 메서드 안에는 아래와 같이 isWhitelisted를 동작시켜 검증하는 코드가 존재했다.
if (isWhitelisted(requestURI)) {
chain.doFilter(request, response);
return;
}
shouldNotFilter 메서드는 true
를 반환할 경우 필터가 적용되지 않으며, false
를 반환할 경우 필터가 적용된다.
@Override
protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
String requestURI = request.getRequestURI();
return WHITELIST_URLS.stream().anyMatch(requestURI::startsWith);
}
간단하게 화이트리스트와 블랙리스트를 구현하여 url을 상세하게 나누어 필터 조건을 주었다.