OncePerRequestFilter란?
: 한 요청에 대해 한번만 실행하는 필터
포워딩(fowarding)이 발생하면 필터 체인(FilterChain)이 다시 동작되는데, 인증은 여러번 처리가 불필요하기에 한번만 처리할 수 있도록 도와주는 역할을 한다.
OncePerRequestFilter의 doFilter()
: 최초 실행 시에 ServletRequest 객체에 자신의 이름과 함께 true값을 함께 세팅해두고, doFilterInternal메소드로 자신의 기능을 수행한다. 그 후에 리다이렉트로 다시 실행되면 요청 객체에 담아뒀던 이전 수행에 대한 여부를 체크한다.
public abstract class OncePerRequestFilter extends GenericFilterBean {
….(생략)
/**
* This {@code doFilter} implementation stores a request attribute for
* "already filtered", proceeding without filtering again if the
* attribute is already there.
* @see #getAlreadyFilteredAttributeName
* @see #shouldNotFilter
* @see #doFilterInternal
*/
@Override
public final void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
if (!(request instanceof HttpServletRequest) || !(response instanceof HttpServletResponse)) {
throw new ServletException("OncePerRequestFilter just supports HTTP requests");
}
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
String alreadyFilteredAttributeName = getAlreadyFilteredAttributeName();
boolean hasAlreadyFilteredAttribute = request.getAttribute(alreadyFilteredAttributeName) != null;
if (skipDispatch(httpRequest) || shouldNotFilter(httpRequest)) {
// Proceed without invoking this filter...
filterChain.doFilter(request, response);
}
else if (hasAlreadyFilteredAttribute) {
if (DispatcherType.ERROR.equals(request.getDispatcherType())) {
doFilterNestedErrorDispatch(httpRequest, httpResponse, filterChain);
return;
}
// Proceed without invoking this filter...
filterChain.doFilter(request, response);
}
else {
// Do invoke this filter...
request.setAttribute(alreadyFilteredAttributeName, Boolean.TRUE);
try {
doFilterInternal(httpRequest, httpResponse, filterChain);
}
finally {
// Remove the "already filtered" request attribute for this request.
request.removeAttribute(alreadyFilteredAttributeName);
}
}
}
}
참고
: https://velog.io/@wjdgkrud/OncePerRequestFilter%EB%9E%80
'Spring > 1-5. Spring Security' 카테고리의 다른 글
Spring Security란? (0) | 2023.11.24 |
---|---|
6) DaoAuthenticationManager와 UserDetailsService 사 (0) | 2023.06.11 |
5) BasicAuthenticationFilter를 사용하여 토큰 인증 (0) | 2023.06.08 |
4) Form Login과 Logout Filter (0) | 2023.06.04 |
3. Spring Security Authentication 구조와 매커니즘 (0) | 2023.06.04 |