Filter

2023. 5. 19. 15:48Spring Framework/Web on Servlet Stack

Spring Web 모듈 필터 개요

Spring Web 모듈은 서블릿 기반 애플리케이션에서 웹 요청을 처리하는 데 유용한 여러 필터를 제공합니다. 이 필터들은 폼 데이터 처리, 전달된 헤더 관리, 얕은 ETag 캐싱, CORS(교차 출처 리소스 공유) 처리를 위한 기능을 제공합니다. 각 필터의 역할에 대해 자세히 살펴보겠습니다.


Form Data 필터

기본적으로 브라우저에서는 HTTP GET 또는 POST 메서드를 통해서만 폼 데이터를 전송할 수 있습니다. 하지만 비-브라우저 클라이언트(예: REST 클라이언트)는 다른 HTTP 메서드인 PUT, PATCH, 또는 DELETE를 사용하여 폼 데이터를 전송할 수 있습니다. Servlet API는 POST 요청에 대해서만 ServletRequest.getParameter*() 메서드를 통해 폼 데이터에 접근할 수 있도록 제한하고 있기 때문에, PUT, PATCH, 또는 DELETE 요청의 폼 데이터는 기본적으로 접근할 수 없습니다.

이를 해결하기 위해 Spring Web 모듈은 FormContentFilter를 제공합니다. 이 필터는 application/x-www-form-urlencoded 콘텐츠 유형의 PUT, PATCH, DELETE 요청을 가로채어 요청 본문에서 폼 데이터를 읽고, ServletRequest를 래핑하여 ServletRequest.getParameter*() 메서드를 통해 폼 데이터를 접근할 수 있도록 합니다. 이는 POST 요청에서 폼 데이터를 처리하는 방식과 유사합니다.

사용 예:

  • PUT, PATCH, DELETE 메서드에서 폼 제출을 지원해야 할 때 FormContentFilter는 폼 필드를 POST 요청과 동일하게 접근할 수 있도록 보장합니다.

Forwarded Headers 필터

여러 프록시(예: 로드 밸런서 또는 리버스 프록시)를 거치는 요청의 경우, 원본 요청의 호스트, 포트 및 스킴이 변경될 수 있습니다. 이로 인해 서버가 클라이언트 요청에 대해 링크나 리디렉션을 생성할 때 문제가 발생할 수 있습니다. 서버는 클라이언트가 본래 요청한 내용과 다른 정보로 처리할 수 있기 때문입니다.

Forwarded HTTP 헤더:

  • RFC 7239는 원본 요청에 대한 정보를 전달하기 위해 Forwarded라는 표준 헤더를 정의합니다.
  • X-Forwarded-Host, X-Forwarded-Port, X-Forwarded-Proto, X-Forwarded-Ssl, X-Forwarded-Prefix와 같은 표준이 아닌 헤더도 많이 사용됩니다.
주요 헤더:
  1. X-Forwarded-Host: 원본 호스트를 전달합니다.
  2. X-Forwarded-Port: 원본 포트를 전달합니다.
  3. X-Forwarded-Proto: 원본 프로토콜(예: http 또는 https)을 전달합니다.
  4. X-Forwarded-Ssl: SSL 사용 여부(on 또는 off)를 전달합니다.
  5. X-Forwarded-Prefix: 원본 URL 경로 접두어를 전달합니다.

ForwardedHeaderFilter:

Spring Web은 ForwardedHeaderFilter를 제공하며, 이 필터는 다음과 같은 역할을 합니다:

  • 전달된 헤더에 따라 요청의 host, port, scheme을 조정합니다.
  • 요청을 수정한 후, 해당 헤더를 제거하여 이후 처리에 영향을 미치지 않도록 합니다.

리버스 프록시를 사용할 때 ForwardedHeaderFilter는 서버가 원본 클라이언트 요청 정보와 일관되게 요청을 처리할 수 있도록 해줍니다.

보안 고려 사항:
  • X-Forwarded-Host와 같은 헤더는 스푸핑될 수 있으므로, 신뢰할 수 있는 프록시만 이러한 헤더를 추가 또는 제거할 수 있도록 해야 합니다. 그렇지 않으면 악의적인 클라이언트가 헤더를 조작하여 애플리케이션을 속일 수 있습니다.
  • removeOnly=trueForwardedHeaderFilter를 구성하여 헤더를 사용하는 대신 제거만 할 수도 있습니다.

Shallow ETag 필터

ETag(엔터티 태그)는 동일한 데이터를 여러 번 전송하지 않도록 돕는 웹 캐싱 메커니즘입니다. Spring Web의 ShallowEtagHeaderFilter는 웹 응답에 대한 얕은 ETag를 생성하는 데 사용됩니다.

작동 방식:

  • 필터는 응답 내용을 캡처하고 MD5 해시를 계산한 후, 이를 ETag 헤더로 설정합니다.
  • 이후 클라이언트가 동일한 ETag 값을 포함한 If-None-Match 헤더를 제공하면, 서버는 304 Not Modified 응답을 반환하여 대역폭을 절약할 수 있습니다.

얕은 ETag와 깊은 ETag:

  • "얕은" ETag는 요청 세부 사항을 고려하지 않고 응답 내용만을 기반으로 ETag를 생성하는 것을 의미합니다. "깊은" ETag는 더 복잡한 체크를 포함할 수 있습니다.
  • 이 필터는 RFC 7232에서 정의된 대로 "약한" ETag(예: W/"etag-value")를 작성하는 기능을 지원합니다.
제한 사항:
  • 이 필터는 CPU 자원을 절약하지는 않습니다. 응답이 완전히 생성된 후에야 ETag를 계산할 수 있기 때문입니다.

CORS (교차 출처 리소스 공유)

CORS는 웹 서버의 리소스를 다른 도메인에서 요청할 수 있도록 하는 메커니즘으로, 현대 웹 애플리케이션에서 필수적입니다. Spring은 다음과 같은 방법으로 CORS에 대한 세밀한 지원을 제공합니다:

  • 어노테이션: Spring MVC 컨트롤러에서 직접 CORS를 구성할 수 있습니다.
  • CorsFilter: CORS 정책을 처리하는 필터로, Spring Security의 필터 체인보다 앞서 배치되어야 합니다.

이를 통해 어떤 출처(origin)가 리소스에 접근할 수 있는지, 어떤 HTTP 메서드와 헤더가 허용되는지, 쿠키와 같은 자격 증명이 요청과 함께 전송될 수 있는지를 정의할 수 있습니다.

Spring Security 통합:

Spring Security를 사용하는 경우, CorsFilter를 사용하여 CORS를 관리하는 것이 좋습니다. Spring Security도 자체적으로 CORS 처리를 구현하고 있기 때문입니다.


Dispatcher Types 및 비동기 요청

ForwardedHeaderFilterShallowEtagHeaderFilter와 같은 필터들이 비동기 요청을 올바르게 처리하려면 DispatcherType.ASYNC와 함께 등록해야 합니다. 이렇게 하면 필터가 비동기 디스패치를 사용하는 요청을 처리할 수 있습니다. 비동기 요청 외에도 에러 처리를 위해 필터들이 DispatcherType.ERROR와 함께 등록되어야 에러 디스패치 시나리오도 처리할 수 있습니다.

AbstractAnnotationConfigDispatcherServletInitializer를 사용하는 경우, 모든 필터는 자동으로 모든 디스패처 타입(REQUEST, ASYNC, ERROR 등)으로 등록됩니다. 하지만 필터를 수동으로 등록하는 경우(Spring Boot에서 FilterRegistrationBean을 사용하는 경우), DispatcherType.ASYNCDispatcherType.ERROR를 명시적으로 포함해야 합니다.


요약

  • FormContentFilter: PUT, PATCH, DELETE 요청에서 폼 데이터를 POST 요청과 동일하게 접근할 수 있게 합니다.
  • ForwardedHeaderFilter: ForwardedX-Forwarded-*와 같은 헤더를 처리하여 올바른 호스트, 포트, 스킴 정보를 유지합니다.
  • ShallowEtagHeaderFilter: 얕은 ETag 기반 캐싱을 제공하여 네트워크 효율성을 향상시킵니다.
  • CorsFilter: 교차 출처 요청에 대한 세밀한 CORS 구성을 가능하게 합니다.

이 필터들은 폼 데이터 제출, 캐싱, 리버스 프록시 통합, CORS 처리 등의 다양한 시나리오를 다룰 수 있도록 하여 웹 애플리케이션의 유연성과 성능을 유지할 수 있게 해줍니다.

 

참고 : [https://docs.spring.io/spring-framework/reference/web/webmvc/filters.html]

'Spring Framework > Web on Servlet Stack' 카테고리의 다른 글

@RequestHeader  (0) 2024.10.09
Annotated Controllers[1]  (1) 2024.10.06
Dispatcher Servlet  (0) 2023.05.02
WebDataBinder  (0) 2023.05.01
Servlet  (0) 2023.04.17