Dev Stories/백엔드(Back-End)
[Spring Security] OncePerRequestFilter를 활용한 인증 제외 URL 설정
레드트레인
2025. 6. 9. 23:00
반응형
OnceRequestFilter는 Spring Security에서 필터 체인의 각 요청마다 한번씩 실행을 하게 된다. Spring Security 설정에 인증 정보를 확인하기 위해 OnceRequestFilter를 상속받아 구현한다. Filter 클래스를 상속받아 구현하게 된다.
OnceRequestFilter shouldNotFilter, doFilterInternal 두개의 추상 메서드가 있다.
package org.springframework.web.filter;
public abstract class OncePerRequestFilter extends GenericFilterBean {
...
/**
* Can be overridden in subclasses for custom filtering control,
* returning {@code true} to avoid filtering of the given request.
* <p>The default implementation always returns {@code false}.
* @param request current HTTP request
* @return whether the given request should <i>not</i> be filtered
* @throws ServletException in case of errors
*/
protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
return false;
}
...
/**
* Same contract as for {@code doFilter}, but guaranteed to be
* just invoked once per request within a single request thread.
* See {@link #shouldNotFilterAsyncDispatch()} for details.
* <p>Provides HttpServletRequest and HttpServletResponse arguments instead of the
* default ServletRequest and ServletResponse ones.
*/
protected abstract void doFilterInternal(
HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException;
...
}
특정 엔드포인트는 필터를 제외
다음은 특정 엔드포인트는 필터를 제외하는 설정이다. 메서드명이 shouldNotFilter인 것을 보면 어떤 결과가 나오는지 예측해 볼 수 있는데, 매칭 될 때 true로 리턴이 되기 때문에 필터를 타지 않습니다.
// 필터를 적용할 엔드포인트 목록
private final List<String> securedUrls = List.of(
"/api/signin",
"/api/signup"
);
@Override
protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
String path = request.getRequestURI();
return securedUrls.stream().anyMatch(path::startsWith);
}
특정 엔드포인트만 필터 적용
특정 엔드포인트만 필터를 적용하고 목록에 없는 나머지 요청은 필터를 건너뛰는 설정이다.
// 필터를 적용할 엔드포인트 목록
private final List<String> excludeUrls = List.of(
"/api/user/profile",
"/api/user/settings"
);
@Override
protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
String path = request.getRequestURI();
return excludeUrls.stream().noneMatch(path::startsWith);
}
와일드카드를 적용하여 패턴 매칭
앞서 설명한 anyMatch, nonMatch의 startsWith()만 사용해서는 엔드포인트 목록의 /api/user/** 과 같은 패턴은 적용할 수 없다. 와일드 카드(*)나 정규 표현식을 사용하려면 직접 매칭 로직을 구현해야 한다.
Spring에서 제공하는 AntPathMatcher를 사용하여 패턴에 맞는 URL을 매칭할 수 있다. pathMather.match(patern, path)로 와일드카드(**)를 활용한 여러 경로를 한 번에 필터링 한다.
// AntPathMatcher
private final AntPathMatcher pathMatcher = new AntPathMatcher();
// 필터를 적용할 엔드포인트 목록 (와일드카드 지원)
private final List<String> securedPatterns = List.of(
"/api/user/**"
);
@Override
protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
String path = request.getRequestURI();
return securedPatterns.stream().noneMatch(pattern -> pathMatcher.match(pattern, path));
}
반응형