Filter

What use?

  • 입력의 검증이 필요할 때
  • 사용자의 정보를 저장하고 싶을 떄
  • 암호화, 복호화를 위해서
  • 로그를 남기고 싶을 때
  • 시간이 오래걸리는 로직은 사용하지 않는 것을 권장

과정

CORS Filter → CSRF Filter → BasicAuthentication Filter

Custom Filter

Filter 구현하기

  • Filter 클래스를 상속받아서 doFilter를 구현해야한다.
  • CustomFilter1.java
package com.chan.ssb.filter;

import jakarta.servlet.*;

import java.io.IOException;
import java.util.logging.Logger;

public class CustomFilter1 implements Filter {

    private final Logger LOG =
            Logger.getLogger(CustomFilter1.class.getName());

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        LOG.info("Authentication Validation is in progress");
        filterChain.doFilter(servletRequest, servletResponse);
    }
}
  • 다음과 같이 인증시 로그를 남기는 필터를 정의했다.
  • CustomFilter2.java
package com.chan.ssb.filter;

import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

public class CustomFilter2 implements Filter {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse res = (HttpServletResponse) servletResponse;

        String username = req.getParameter("username");

        if(username.equals("test")){
            res.sendError(HttpServletResponse.SC_BAD_REQUEST, "test");
            return;
        }

        filterChain.doFilter(servletRequest, servletResponse);
    }
}
  • 입력으로 들어온 username이 test일 때, 오류를 반환하는 필터를 구현하였다.

Filter 적용하기

  • SpringSecurityConfiguration.java
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {

        http.csrf((csrf)-> csrf.csrfTokenRequestHandler(requestHandler).ignoringRequestMatchers("/user/**", "/authority", "/h2-console/**")
            .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()))
            .addFilterAfter(new CsrfCookieFilter(), BasicAuthenticationFilter.class)
            .addFilterBefore(new CustomFilter2(), BasicAuthenticationFilter.class)
//            .addFilterAfter(new CustomFilter1(), BasicAuthenticationFilter.class)
            .addFilterAt(new CustomFilter1(), BasicAuthenticationFilter.class);



        return http.build();
    }

  • addFilterBefore / addFilterAfter / addFilterAt 다음 세가지를 이용해서 적용이 가능하다.
  • addFilterBefore(arg1, arg2): arg1 필터를 arg2 필터 이전에 적용한다.
  • addFilterAfter(arg1, arg2): arg1 필터를 arg2 필터 이후에 적용한다.
  • addFilterAt(arg1, arg2): arg1 필터를 arg2 필터는 같이 실행하는데 무엇이 먼저 실행하는지 보장할 수 없다.

GenericFilterBean, OncePerRequestFilter

기존 Filter의 문제점

  • Filter는 Spring 정보를 포함하지 않는다.
  • 해당 문제를 해결하기 위한 필터들임

GenericFilterBean, OncePerRequestFilter

  • GenericFilterBean는 로직상 여러번 실행할 수 있음
  • OncePerRequestFilter는 한번만 호출을 보장하는 필터!
  • doFilterInternal()을 통해서 구현한다.
  • OncePerRequestFilter를 권장
profile
백엔드 개발자가 꿈인 컴공과

0개의 댓글

Powered by GraphCDN, the GraphQL CDN