Git :)

ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • ch17 전역 메서드 보안: 사전 및 사후 필터링
    IT 서적/Spring Security In Action 2024. 1. 12. 15:51
    728x90

    # 사전 및 사후 필터링의 필요성

    • 메서드 호출은 허용하면서도 메서드로 보내는 매개 변수가 몇 가지 규칙을 따르는지 확인하고 싶을 수 있다.
    • 메서드를 호출한 후 호출자가 반환된 값의 승인된 부분만 받을 수 있게 하려는 시나리오도 있을 수 있다.
    • 이러한 기능을 필터링이라고 하며 두 가지 범주로 분류한다.
      • 사전 필터링 : 프레임워크가 메서드를 호출하기 전에 매개 변수의 값을 필터링한다.
      • 사후 필터 : 프레임워크가 메서드를 호출한 후 반환된 값을 필터링한다.
    • @PreFilter 어노테이션이 지정된 메서드를 가로채고 정의된 기준에 따라 매개 변수로 제공되는 컬렉션의 값을 필터링한다.
    • 아래의 소스를 참고해보자.
    @Service
    public class ProductService {
    
        @PreFilter("filterObject.owner == authentication.name")
        public List<Product> sellProduct(List<Product> products) {
            return products ;
        }
    
    }
    @Configuration
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    public class ProductConfig extends WebSecurityConfigurerAdapter {
    
        @Bean
        public UserDetailsService userDetailsService() {
            var manager = new InMemoryUserDetailsManager() ;
    
            var u1 = User.withUsername("nikolai")
                    .password("12345")
                    .authorities("READ")
                    .build() ;
    
            var u2 = User.withUsername("julien")
                    .password("12345")
                    .authorities("READ")
                    .build() ;
    
            manager.createUser(u1);
            manager.createUser(u2);
    
            return manager ;
        }
    
        @Bean
        public PasswordEncoder passwordEncoder() {
            return NoOpPasswordEncoder.getInstance() ;
        }
    
    }
    @RestController
    public class Controller {
    
        @Autowired
        ProductService productService ;
    
        @GetMapping("/sell")
        public List<Product> sellProd() {
            List<Product> products = new ArrayList<>() ;
    
            products.add(new Product("beer", "nikolai")) ;
            products.add(new Product("candy", "nikolai")) ;
            products.add(new Product("chocolate", "julien")) ;
    
            return productService.sellProduct(products) ;
        }
    }

     

    • 결과

     

    • 주의할 점은 주어진 컬렉션을 애스펙트가 변경한다는 사실이다.
    • 애스펙트가 같은 인스턴스에서 기준에 맞지 않는 요소를 제거하는 것이다.
    • 변경이 불가능한 컬렉션을 제공하면 필터링 애스펙트가 컬렉션의 내용을 변경할 수 없어 실행 시 예외가 발생한다.

     

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

    •  아래의 소스코드와 같이 List가 존재하는 비즈니스 로직을 수행시킨 후, 필터링 작업이 필요할 때 @PostFilter를 사용하여 사후 필터링을 구현할 수 있다.
    @Service
    public class ProductService {
    
        @PostFilter("filterObject.owner == authentication.name")
        public List<Product> sellProduct(List<Product> products) {
    
            products.add(new Product("beer", "nikolai")) ;
            products.add(new Product("candy", "nikolai")) ;
            products.add(new Product("chocolate", "julien")) ;
            
            return products ;
        }
    }
    728x90