본문 바로가기
개발(라이브러리,프레임워크)/Spring boot

xss filter & Interceptor

by zieunee 2020. 1. 9.
반응형

requestbody json Filter

 

Post방식으로 application/json 타입의 데이터를 Servlet Filter Spring Interceptor 에서 처리하기 위해서 HttpServletRequest의 InputStream을 읽어들여야 한다.

그러나 HttpServletRequest의 InputStream은 한 번 읽으면 다시 읽을 수 없다

우선 wrapper 객체를 하나 만들어서 일단 InputStream을 읽어서 작업후 >>이미 읽었던 데이터로 다시 InputStream을 생성해 돌려주도록 만드는 방법이 존재한다.

 

결국 inputstream 으로 한번 읽어들이면 다시 읽어서 다시 inputstream으로 생성해 돌려줘야함

 

filter , Interceptor 차이?

 

공통점 : Interceptor filter Servlet 단위에서 실행됨

Vs(번외) AOP 메소드 앞에 proxy 패턴의 형태에서 실행됨

 

Filter 

  • 그림과 같이 filter 가장 밖에 있음
  • Dispatcher Servlet 단을 처리함

 

Interceptor

  • DispatcherServlet에서 Handler(Controller) 가기전에 정보 처리임
  • preHandle같은 경우 controller 들어가기 전에 실행 되기 때문에 false 되면 controller 보내지지 않음 (동작이 안됨)

 

순서

Request -> Servlet Filter -> Dispatcher Servlet -> HandlerInterceptor -> Controller

 

 

filter 예시

@WebFilter(urlPatterns= "/api/*")추가 (web.xml 넣는것 대신)

package com.example.springstudy.filter;



import javax.servlet.*;

import javax.servlet.annotation.WebFilter;

import java.io.IOException;



@WebFilter(urlPatterns= "/api/*")

public class TestFilter implements Filter {

    @Override

    public void init(FilterConfig filterConfig) throws ServletException {

                //filter 생성 시 처리

    }



    @Override

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        //다음 Filter 실행 전 처리 (preHandle)

       

        //다음 filter-chain에 대한 실행 (filter-chain의 마지막에는 Dispatcher servlet실행)

                filterChain.doFilter(servletRequest, servletResponse);

       

        //다음 Filter 실행 후 처리 (postHandle)

    }



    @Override

    public void destroy() {

                //filter 제거 시 처리 (보통 자원의 해제처리를 한다.)

    }

}

 

 

Interceptor 예시

public class MyInterceptor implements HandlerInterceptor{

        // controller로 보내기 전에 처리하는 인터셉터

        // 반환이 false라면 controller로 요청을 안함

        // 매개변수 Object는 핸들러 정보를 의미한다. ( RequestMapping , DefaultServletHandler )

        @Override

        public boolean preHandle(

                        HttpServletRequest request, HttpServletResponse response,

                        Object obj) throws Exception {

                

                System.out.println("MyInterCeptor - preHandle");

                return false;

        }



        // controller의 handler가 끝나면 처리됨

        @Override

        public void postHandle(

                        HttpServletRequest request, HttpServletResponse response,

                        Object obj, ModelAndView mav)

                        throws Exception {

        }



        // view까지 처리가 끝난 후에 처리됨

        @Override

        public void afterCompletion(

                        HttpServletRequest request, HttpServletResponse response,

                        Object obj, Exception e)

                        throws Exception {

        }

}

WebAppConfiguration.java 추가

  @Autowired

        @Qualifier(value = "httpInterceptor")

        private HandlerInterceptor interceptor;



        @Override

        public void addInterceptors(InterceptorRegistry registry) {

                registry.addInterceptor(interceptor) .addPathPatterns("/**");



        }

 

실행 방법

데이터를 주고 받는 형태가 JSON 형태이다.(Requestbody) Parameter 주고 받는 형태가 아니었기 때문에 인터넷에 나와있는 일반적인 필터링 방법과 네이버에서 제공하는 루시도 사용하기 애매한 방법이였다.

 

그러던 도중>> requestbody 받는 데이터는 HttpServletRequest의 InputStream을  읽어들여 처리할 있다는 글을 보고 데이터를 처리 해줬는데 Message 없다는 오류가 떴다.

 

이유를 알아보니 한번 inputstream에서 빠져나와 작업을 하게되면 다시 없다는것 ! 그래서 다시 inputstream 넣어줘야 한다.

 

그래서 reqeustWrapper.java 서블렛스트림을 오버라이드 시켜 작업을 해줬다.

 

이후 필터링을 하는게 아니라 아예 필터해야할 값에 걸리게 되면 api 보내지 못하게 처리하려고 만들었다.

 

처음에는 Interceptor 써서 preHandle requestWrapper객체로 함수를 불러와 값을 구분해주고 필터에 걸리면 false 리턴해주는 방식으로 만들었지만(Controller 가지 못하게 막는 방식), 너무 불편하고 굳이 Interceptor까지 사용해야하나 라는 생각이 들어 doFIilter 있는 부분에 체크를 해줘서 filter 값이라면 doFilter 돌아가지 못하게 하는 방식으로 했더니 성공하였다

 

 

반응형

'개발(라이브러리,프레임워크) > Spring boot' 카테고리의 다른 글

Bean 생성 관리  (0) 2021.03.29
intellij 초기 설정 , vue.js와 연동  (0) 2021.03.28
Spring MVC , Spring Boot  (0) 2019.11.19
REST API  (0) 2019.11.18
Spring Boot VS Spring  (0) 2019.06.28