Filters

Dev.Hammy·2024년 3월 26일
0

반응형 스택에서 이에 상응하는 내용 보기

spring-web 모듈은 몇 가지 유용한 필터를 제공합니다:

Form Data

브라우저는 HTTP GET 또는 HTTP POST를 통해서만 양식 데이터를 제출할 수 있지만 브라우저가 아닌 클라이언트는 HTTP PUT, PATCH 및 DELETE를 사용할 수도 있습니다. Servlet API에는 HTTP POST에 대해서만 양식 필드 액세스를 지원하기 위한 ServletRequest.getParameter*() 메소드가 필요합니다.

spring-web 모듈은 FormContentFilter를 제공하여 application/x-www-form-urlencoded 콘텐츠 유형으로 HTTP PUT, PATCH 및 DELETE 요청을 가로채고, 요청 본문에서 양식 데이터를 읽고, ServletRequest를 래핑하여 ServletRequest.getParameter*() 메소드 계열을 통해 사용할 수 있는 양식 데이터입니다.

Forwarded Headers

반응형 스택에서 이에 상응하는 내용 보기

요청이 로드 밸런서와 같은 프록시를 통과함에 따라 호스트, 포트 및 체계가 변경될 수 있으며 이로 인해 클라이언트 관점에서 올바른 호스트, 포트 및 체계를 가리키는 링크를 생성하는 것이 어려워집니다.

RFC 7239는 프록시가 원래 요청에 대한 정보를 제공하는 데 사용할 수 있는 Forwarded HTTP 헤더를 정의합니다.

Non-standard Headers

X-Forwarded-Host, X-Forwarded-Port, X-Forwarded-Proto, X-Forwarded-SslX-Forwarded-Prefix를 포함한 다른 비표준 헤더도 있습니다.

X-Forwarded-Host

표준은 아니지만 X-Forwarded-Host: <host>는 원래 호스트를 다운스트림 서버와 통신하는 데 사용되는 사실상의 표준 헤더입니다. 예를 들어, example.com/resource 요청이 요청을 localhost:8080/resource로 전달하는 프록시로 전송되면 X-Forwarded-Host: example.com 헤더가 서버에 전송될 수 있습니다. 원래 호스트는 example.com이었습니다.

X-Forwarded-Port

표준은 아니지만 X-Forwarded-Port: <port>는 원래 포트를 다운스트림 서버에 전달하는 데 사용되는 사실상의 표준 헤더입니다. 예를 들어, example.com/resource 요청이 요청을 localhost:8080/resource로 전달하는 프록시로 전송되면 X-Forwarded-Port: 443 헤더가 전송되어 원래 443 포트가 서버에 있음을 알릴 수 있습니다.

X-Forwarded-Proto

표준은 아니지만 X-Forwarded-Proto: (https|http)는 원래 프로토콜(예: https / https)을 다운스트림 서버에 전달하는 데 사용되는 사실상의 표준 헤더입니다. 예를 들어, example.com/resource의 요청이 요청을 localhost:8080/resource로 전달하는 프록시로 전송되면 X-Forwarded-Proto: https 헤더가 전송되어 원래 https 프로토콜이 서버에 있음을 알릴 수 있습니다.

X-Forwarded-Ssl

표준은 아니지만 X-Forwarded-Ssl: (on|off)는 원래 프로토콜(예: https / https)을 다운스트림 서버에 전달하는 데 사용되는 사실상의 표준 헤더입니다. 예를 들어, example.com/resource 요청이 요청을 localhost:8080/resource로 전달하는 프록시로 전송되면 X-Forwarded-Ssl: on 헤더가 원래 프로토콜이 https였음을 서버에 알립니다.

X-Forwarded-Prefix

표준은 아니지만 X-Forwarded-Prefix: <prefix>는 원래 URL 경로 접두어를 다운스트림 서버에 전달하는 데 사용되는 사실상의 표준 헤더입니다.

X-Forwarded-Prefix의 사용은 배포 시나리오에 따라 다를 수 있으며 대상 서버의 경로 접두사를 대체, 제거 또는 앞에 추가할 수 있도록 유연해야 합니다.

Scenario 1: Override path prefix

https://example.com/api/{path} -> http://localhost:8080/app1/{path}

접두사는 캡처 그룹 {path} 앞의 경로 시작입니다. 프록시의 경우 접두사는 /api이고 서버의 경우 접두사는 /app1입니다. 이 경우 프록시는 X-Forwarded-Prefix: /api를 보내 원래 접두사 /api가 서버 접두사 /app1을 재정의하도록 할 수 있습니다.

Scenario 2: Remove path prefix
때때로 응용 프로그램에서 접두사를 제거하려고 할 수도 있습니다. 예를 들어 다음 프록시-서버 매핑을 고려해보세요.

https://app1.example.com/{path} -> http://localhost:8080/app1/{path}
https://app2.example.com/{path} -> http://localhost:8080/app2/{path}

프록시에는 접두사가 없지만 app1app2 애플리케이션에는 각각 경로 접두사 /app1/app2가 있습니다. 프록시는 X-Forwarded-Prefix:를 전송하여 빈 접두사가 서버 접두사 /app1/app2를 재정의하도록 할 수 있습니다.

[Note]
이 배포 시나리오의 일반적인 경우는 프로덕션 응용 프로그램 서버별로 라이선스를 지불하는 것이며, 비용을 줄이기 위해 서버당 여러 응용 프로그램을 배포하는 것이 좋습니다. 또 다른 이유는 서버 실행에 필요한 리소스를 공유하기 위해 동일한 서버에서 더 많은 응용 프로그램을 실행하는 것입니다.

이러한 시나리오에서는 동일한 서버에 여러 애플리케이션이 있으므로 애플리케이션에는 비어 있지 않은 컨텍스트 루트가 필요합니다. 그러나 이는 애플리케이션이 다음과 같은 이점을 제공하는 다른 하위 도메인을 사용할 수 있는 공개 API의 URL 경로에 표시되어서는 안 됩니다.

  • 보안이 추가되었습니다. 동일 원산지 정책

  • 애플리케이션의 독립적인 확장(다른 도메인은 다른 IP 주소를 가리킴)

Scenario 3: Insert path prefix
다른 경우에는 접두사를 추가해야 할 수도 있습니다. 예를 들어 다음 프록시-서버 매핑을 고려해보세요.

https://example.com/api/app1/{path} -> http://localhost:8080/app1/{path}

이 경우 프록시의 접두사는 /api/app1이고 서버의 접두사는 /app1입니다. 프록시는 X-Forwarded-Prefix: /api/app1을 보내 원래 접두사 /api/app1이 서버 접두사 /app1을 재정의하도록 할 수 있습니다.

ForwardedHeaderFilter

ForwardedHeaderFilter는 a) Forwarded 헤더를 기반으로 호스트, 포트 및 구성표를 변경하고 b) 추가 영향을 제거하기 위해 해당 헤더를 제거하기 위해 요청을 수정하는 서블릿 필터입니다. 필터는 요청 래핑에 의존하므로 원래 요청이 아닌 수정된 요청에 작동해야 하는 RequestContextFilter와 같은 다른 필터보다 먼저 주문되어야 합니다.

Security Considerations

헤더가 의도한 대로 프록시에 의해 추가되었는지 아니면 악의적인 클라이언트에 의해 추가되었는지 애플리케이션이 알 수 없으므로 전달된 헤더에 대한 보안 고려 사항이 있습니다. 이것이 바로 외부에서 들어오는 신뢰할 수 없는 Forwarded 헤더를 제거하도록 신뢰 경계의 프록시를 구성해야 하는 이유입니다. 또한 removeOnly=trueForwardedHeaderFilter를 구성할 수도 있습니다. 이 경우 헤더는 제거되지만 사용되지 않습니다.

Dispatcher Types

비동기 요청 및 오류 디스패치를 지원하려면 이 필터를 DispatcherType.ASYNCDispatcherType.ERROR와 매핑해야 합니다. Spring Framework의 AbstractAnnotationConfigDispatcherServletInitializer(서블릿 구성 참조)를 사용하는 경우 모든 필터는 모든 디스패치 유형에 대해 자동으로 등록됩니다. 그러나 web.xml을 통해 또는 Spring Boot에서 FilterRegistrationBean을 통해 필터를 등록하는 경우 DispatcherType.REQUEST 외에 DispatcherType.ASYNCDispatcherType.ERROR를 포함해야 합니다.

Shallow ETag

ShallowEtagHeaderFilter 필터는 응답에 기록된 콘텐츠를 캐시하고 여기에서 MD5 해시를 계산하여 "얕은" ETag를 생성합니다. 다음에 클라이언트가 보낼 때 동일한 작업을 수행하지만 계산된 값을 If-None-Match 요청 헤더와 비교하여 두 값이 동일하면 304(NOT_MODIFIED)를 반환합니다.

이 전략은 각 요청에 대해 전체 응답을 계산해야 하므로 네트워크 대역폭은 절약하지만 CPU는 절약하지 않습니다. 상태 변경 HTTP 메서드와 If-MatchIf-Unmodified-Since와 같은 기타 HTTP 조건부 요청 헤더는 이 필터의 범위를 벗어납니다. 컨트롤러 수준의 다른 전략은 계산을 방지하고 HTTP 조건부 요청을 더 광범위하게 지원할 수 있습니다. HTTP 캐싱을 참조하세요.

이 필터에는 W/"02a2d595e6ed9a0b24f027f2b63b134d6"(RFC 7232 섹션 2.3에 정의됨)과 유사한 약한 ETag를 쓰도록 필터를 구성하는 writeWeakETag 매개변수가 있습니다.

비동기 요청을 지원하려면 이 필터를 DispatcherType.ASYNC와 매핑하여 필터가 마지막 비동기 디스패치 끝까지 ETag를 지연하고 성공적으로 생성할 수 있도록 해야 합니다. Spring Framework의 AbstractAnnotationConfigDispatcherServletInitializer(서블릿 구성 참조)를 사용하는 경우 모든 필터는 모든 디스패치 유형에 대해 자동으로 등록됩니다. 그러나 web.xml을 통해 또는 FilterRegistrationBean을 통해 Spring Boot에 필터를 등록하는 경우 DispatcherType.ASYNC를 포함해야 합니다.

CORS

반응형 스택에서 이에 상응하는 내용 보기

Spring MVC는 컨트롤러의 주석을 통해 CORS 구성에 대한 세부적인 지원을 제공합니다. 그러나 Spring Security와 함께 사용할 경우 Spring Security의 필터 체인보다 먼저 주문해야 하는 내장 CorsFilter를 사용하는 것이 좋습니다.

자세한 내용은 CORSCORS 필터 섹션을 참조하세요.

0개의 댓글