Spring/스프링 시큐리티 인 액션

[17장] 전역 메서드 보안: 사전 및 사후 필터링

꾸준함. 2025. 6. 5. 11:24

주의

이 책은 Spring Security 5 버전을 기준으로 작성되었으므로, Spring Boot 3.X 버전에서는 일부 클래스가 더 이상 사용되지(deprecated) 않을 수 있습니다.

 

서론

  • 메서드 호출은 허용하면서도 메서드로 보내는 매개변수가 몇 가지 규칙을 따르는지 확인하고 싶을 수도 있음
  • 또는 메서드를 호출한 뒤 호출자가 반환된 값의 승인된 부분만 받을 수 있게 하려는 시나리오도 있을 수 있음
  • 이러한 기능을 필터링이라고 하며 다음의 두 범주로 분류함
    • 사전 필터링 (prefiltering): 프레임워크가 메서드를 호출하기 전에 매개변수의 값을 필터링
    • 사후 필터링 (postfiltering): 프레임워크가 메서드를 호출한 뒤 반환된 값을 필터링

 

  • 필터링은 호출 권한 부여와 다른 방식으로 작동함
    • 필터링을 적용하면 프레임워크는 매개변수나 반환된 값이 권한 부여 규칙을 준수하지 않아도 메서드를 호출하며 예외를 던지지 않는 대신 지정한 조건을 준수하지 않는 요소를 필터링함

 

  • 필터링은 컬렉션과 배열에만 적용할 수 있음
    • 사전 필터링은 메서드가 객체의 배열이나 컬렉션을 받아야 이용할 수 있음
    • 프레임워크는 개발자가 정의한 규칙에 따라 해당 컬렉션이나 배열을 필터링함
    • 사후 필터링 또한 메서드가 컬렉션이나 배열을 반환해야 필터링을 적용할 수 있음

 

https://livebook.manning.com/book/spring-security-in-action/chapter-17/1

 

1. 메서드 권한 부여를 위한 사전 필터링 적용

  • 필터링을 이용하면 누군가가 메서드를 호출할 때 메서드 매개변수로 전송된 값을 검증하도록 프레임워크에 지시할 수 있음
    • 프레임워크는 주어진 기준을 충족하지 않는 값을 필터링하고 기준을 충족하는 값으로만 메서드를 호출
    • 해당 기능을 사전 필터링이라고 지칭

 

  • 스프링 시큐리티는 Aspect로 필터링을 구현함
    • Aspect는 특정 메서드를 가로채고 다른 명령으로 메서드를 보강할 수 있음
    • 사전 필터링에서 Aspect는 @PreFilter 어노테이션이 지정된 메서드를 가로채고 정의된 기준에 따라 매개변수로 제공되는 컬렉션 값을 필터링함

 

https://livebook.manning.com/book/spring-security-in-action/chapter-17/14

 

  • 사전 필터링은 @PreFilter 어노테이션의 값으로 권한 부여 규칙을 설정함
    • SpEL 식으로 제공하는 이러한 규칙에서 filterObject로 메서드의 매개변수로 제공하는 컬렉션 또는 배열 내의 모든 요소를 참조함
    • Aspect가 새로운 컬렉션이나 배열을 반환하는 것이 아니라 전달된 컬렉션이나 배열을 필터링하는 것이므로 전달된 매개변수가 immutable이면 예외 발생

 

  • 아래 예제는 사용자가 상품을 사고파는 애플리케이션이며 백엔드는 /sell 엔드포인트를 구현
    • 사용자가 상품을 판매하려고 하면 애플리케이션 프런트엔드가 해당 엔드포인트를 호출하지만 로그인한 사용자는 본인 상품만 팔 수 있음
    • 매개변수로 받은 상품을 파기 위해 서비스 메서드를 호출하는 간단한 시나리오를 구현하기 위해 @PreFilter 어노테이션으로 메서드가 현재 로그인한 사용자의 상품만 받을 수 있도록 구현함

 

 

https://livebook.manning.com/book/spring-security-in-action/chapter-17/22

 

2. 메서드 권한 부여를 위한 사후 필터링 적용

  • 사후 필터링도 사전 필터링과 비슷하게 Aspect에 의존함
    • 해당 Aspect는 메서드를 호출하도록 허용하지만 메서드가 반환되면 반환된 값이 정의된 규칙을 준수하는지 확인
    • 사후 필터링도 사전 필터링과 마찬가지로 메서드가 반환하는 컬렉션이나 배열을 변경하며 반환된 컬렉션의 요소가 따라야 하는 기준을 지정할 수 있음
    • 사후 필터 Aspect는 반환된 컬렉션이나 배열에서 이러한 규칙을 따르지 않는 요소를 필터링함

 

https://livebook.manning.com/book/spring-security-in-action/chapter-17/52

 

  • 사후 필터링을 적용하려면 @PostFilter 어노테이션을 이용해야 함
    • 어노테이션의 값의 권한 부여 규칙을 SpEL 식으로 지정하면 해당 규칙이 필터링 Aspect에 적용됨
    • 또한 사후 필터링도 사전 필터링과 비슷하게 배열과 컬렉션만 대상으로 작업하므로 @Postfilter 어노테이션은 컬렉션이나 배열을 반환하는 메서드에만 지정할 수 있음

 

 

 

3. 스프링 데이터 레포지토리에 필터링 이용

  • 스프링 부트 애플리케이션에서 SQL 또는 NoSQL과 같은 데이터베이스에 연결하기 위한 상위 계층으로는 스프링 데이터가 자주 이용됨
  • 레포지토리 수준에 필터를 적용하는 두 가지 방법이 있음
    • 첫 번째 방식은 @PreFilter와 @PostFilter 어노테이션을 이용하는 것
    • 두 번째 방식은 쿼리에 직접 권한 부여 규칙을 통합하는 것

 

  • 레포지토리에 @PreFilter 어노테이션을 적용하는 사전 필터링은 애플리케이션의 다른 계층에 적용하는 것과 같지만 사후 필터링은 상황이 다름
    • 레포지토리 메서드에 @PostFilter를 적용하는 것은 기술적으로는 문제가 없지만 성능 관점에서는 대부분 좋지 않은 선택
    • 모든 레코드를 가져온 뒤 직접 필터링할 경우 OOM 에러가 발생할 수 있음
    • 처음부터 필요한 것만 데이터베이스에서 검색하는 것이 레코드를 필터링하는 것보다 성능 면에서 유리함

 

https://livebook.manning.com/book/spring-security-in-action/chapter-17/1

 

 

참고

스프링 시큐리티 인 액션

반응형