티스토리 뷰

Skill/spring

[springboot] Filter 설정

진열사랑 2020. 6. 25. 15:20

출처 : https://linked2ev.github.io/gitlog/2019/09/15/springboot-mvc-13-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-MVC-Filter-%EC%84%A4%EC%A0%95/

Filter란?

필터란? 거른다는 뜻이다. 서블릿의 ServletContext 기능으로 사용자에 의해 서블릿이 호출 되긴 전/후로 사용자 요청/응답의 헤더 정보 등을 검사 및 설정할 수가 있다.

 

Filter와 Interceptor 비교

  • 필터는 DispatcherServlet 앞에서 먼저 동작하고, 인터셉터는 DispatcherServlet에서 Controllr(Handler) 사이에서 동작한다.
  • 필터
    • 웹 어플리케이션의 Context의 기능
    • 스프링 기능을 활용하기에 어려움
    • 일반적으로 인코딩, CORS, XSS, LOG, 인증, 권한 등 을 구현
  • 인터셉터
    • 스프링의 Spring Context의 기능이며 일종의 빈
    • 스프링 컨테이너이기에 다른 빈을 주입하여 활용성이 좋음
    • 다른 빈을 활용 가능하기에 인증, 권한 등을 구현함



스프링부트에서 Filter 설정

스프링에서는 웹 어플리케이션 컨텍스트를 설정할 수 있는 web.xml 파일을 통한 필터를 설정한 부분이다.

web.xml

 

하지만, 스프링부트에서는 이제 web.xml 파일이 없어졌다. 대신 프로그래밍 방식으로 설정할 수 있으며 2가지 방법이 있다.

첫번째는 자바프로그래밍 방식으로 FilterRegistrationBean을 이용해서 필터로 등록한 후에 WebMvcConfigurer을 상속 받아 설정 후 빈으로 등록하는 방식

두번째는 내장 컨테이너를 사용하는 스프링부트에서 지원하는 애너테이션인 @WebServlet, @WebFilter  @WebListener 선언해서 자동 등록 후 @ServletComponentScan로 이용하는 방식

XSS, CORS 처리하는 필터라는 가정하에 CORSFilter는 첫번째 방식으로 XSSFilter는 애너테이션 방식으로 다르게 설정해보겠다.

 

방법 1) FilterRegistrationBean으로 필터 등록


org.springframework.boot.web.servlet의 FilterRegistrationBean를 사용해 CORSFilter 클래스를 설정파일에서 빈으로 등록하는 방식이다.

 

방법 2) @WebFilter 애너테이션 필터 등록


스프링부트에서 지원하는 @WebFilter 애너테이션으로 자동 등록 후에 @ServletComponentScan으로 사용하는 방식이다.

필터 내 메서드 설명

  • init()
    • 웹 컨테이너(톰캣)이 시작될 때 필터 최초 한 번 인스턴스 생성
  • doFilter()
    • 클라이언트의 요청 시 전/후 처리
    • FilterChain을 통해 전달
  • public void destroy()
    • 필터 인스턴스가 제거될 때 실행되는 메서드, 종료하는 기능

예제

 

@Configuration
public class FilterConfiguration implements WebMvcConfigurer {
	
	@Bean
	public FilterRegistrationBean getFilterRegistrationBean() {
		FilterRegistrationBean registrationBean = new FilterRegistrationBean(new CORSFilter());
		registrationBean.setOrder(Integer.MIN_VALUE);
		//registrationBean.addUrlPatterns("/*");
		registrationBean.setUrlPatterns(Arrays.asList("/board/*"));
		return registrationBean;
	}
}
//--------------
package com.mindone.okch.common.filter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

public class RequestWrapper extends HttpServletRequestWrapper {

    public RequestWrapper(HttpServletRequest servletRequest) {
        super(servletRequest);
    }
 
    public String[] getParameterValues(String parameter) {
 
        String[] values = super.getParameterValues(parameter);
        if (values==null)  {
        	return null;
        }
        int count = values.length;
        String[] encodedValues = new String[count];
        for (int i = 0; i < count; i++) {
        	encodedValues[i] = cleanXSS(values[i]);
        	System.out.println("RequestWrapper.getParameterValues("+parameter+") : " + encodedValues[i]);
        }
        return encodedValues;
    }
 
    public String getParameter(String parameter) {
        String value = super.getParameter(parameter);
        if (value == null) {
        	return null;
        }
        
        System.out.println("RequestWrapper.getParameter() : " + cleanXSS(value));
        return cleanXSS(value);
    }
 
    public String getHeader(String name) {
        String value = super.getHeader(name);
        if (value == null)
        	return null;
        return cleanXSS(value);
 
    }
 
    private String cleanXSS(String value) {
        //You'll need to remove the spaces from the html entities below
        value = value.replaceAll("<", "& lt;").replaceAll(">", "& gt;");
        value = value.replaceAll("\\(", "& #40;").replaceAll("\\)", "& #41;");
        value = value.replaceAll("'", "& #39;");
        value = value.replaceAll("eval\\((.*)\\)", "");
        value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\"");
        value = value.replaceAll("script", "");
        return value;
    }

}

public class XssApiFilter implements Filter {
	
	FilterConfig filterConfig;
	
    public void init(FilterConfig filterConfig) throws ServletException {
        this.filterConfig = filterConfig;
    }
 
    public void destroy() {
        this.filterConfig = null;
    }
 
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
        throws IOException, ServletException {
 
        chain.doFilter(new RequestWrapper((HttpServletRequest) request), response);
 
    }

}
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함