Spring/Spring Security

[Spring Security] 전역 메서드 보안

꾸준함. 2024. 10. 9. 10:58

전역 메서드 보안 (Global Method Security)

  • 클래스나 메서드 단위에서 특정 권한을 가진 사용자만 메서드를 실행하도록 제한할 수 있는 기능
  • 전역 메서드 보안에서 수행할 수 있는 두 가지 주요 작업은 다음과 같음
    • 호출 권한 부여
    • 필터링

 

  • 기본적으로 스프링 시큐리티에서는 전역 메서드 보안이 비활성화 상태로 제공되기 때문에 해당 기능을 사용하기 위해서는 전역 메서드 보안을 우선 활성화해줘야 함
    • Spring Security 6 버전에서는 @EnableMethodSecurity 하위 버전에서는 @EnableGlobalMethodSecurity 어노테이션 부여
    • 전역 메서드 보안을 활성화시키면 스프링의 Aspect(보안 Aspect)가 하나 활성화 됨
    • 해당 Aspect는 호출을 가로채어 권한 부여 규칙이 충족되지 않으면 서비스로 호출을 제한함

 

 

1. 호출 권한 부여

  • 특정 메서드가 실행되기 전, 현재 사용자에게 해당 메서드를 실행할 권한이 있는지를 검사하는 것을 의미
  • 특정 메서드가 호출되기 전, 사용자의 인증 정보나 권한을 검증하여 메서드 실행을 허용하거나 차단할 수 있음
  • 메서드에 제공된 파라미터에 따라 접근할 수 있는지 여부를 판단 가능
  • 메서드의 결과에 따라 어떠한 결정을 해야 할 때 이를 활용 가능
  • 호출 권한 부여는 다음과 같이 크게 두 가지로 분류
    • 사전 권한 부여(PreAuthorization): 메서드 호출 전 권한 부여 규칙을 검사하는 프레임워크
    • 사후 권한 부여(PostAuthorization): 메서드 호출 후 권한 부여 규칙을 검사하는 프레임워크

 

1.1 사전 권한 부여

  • 메서드가 실행되기 전에 현재 사용자(또는 인증된 사용자)의 권한을 검사하는 방식
  • Spring Security는 메서드가 호출되기 전에 사용자의 권한을 확인하고, 해당 권한이 충분하지 않으면 메서드를 실행하지 않고 예외를 발생시킴
  • 이를 통해, 특정 메소드에 대해 특정 사용자만 접근할 수 있도록 제한할 수 있음
  • @PreAuthorize 어노테이션은 주로 이 기능을 구현하는 데 사용되며, 권한, 역할, 사용자 소유권 등을 검사하여 권한을 부여

 

 

 

1.2 사후 권한 부여

  • 메서드가 실행된 후, 반환된 결과를 기반으로 접근 권한을 검사하는 방식
  • 메서드가 먼저 실행된 후, 반환된 객체나 데이터가 특정 조건을 충족하는지 검사한 후에 사용자에게 결과를 반환할지 여부를 결정
  • @PostAuthorize 애너테이션은 사후 권한 부여를 구현하는 데 사용되며, 반환된 값에 대한 검증을 수행
  • 메서드의 로직이 어떤 상태를 변경하는 WRITE, MODIFY, DELETE 같은 기능을 포함하고 있을 경우 멱등성을 보장하지 못할 수 있기 때문에 주의 필요
    • 권한이 유효하지 않아 예외가 던져지더라도 메서드 혹은 데이터에 대한 롤백은 따로 진행되지 않음
    • 사후 권한 부여 기능에서 발생하는 예외는 트랜잭션이 커밋된 이후에 발생하는 것이기 때문에 @Transactional 어노테이션을 부여하더라도 제대로 동작하지 않을 수 있음

 

 

 

2. 필터링

  • 리스트나 컬렉션과 같은 다수의 데이터가 반환될 때, 사용자의 권한에 따라 일부 데이터만 필터링하여 반환 가능
  • 필터링 방식은 @PreFilter 및 @PostFilter 어노테이션을 사용하여 구현 가능
    • @PreFilter: 메서드 실행 전에 전달된 데이터 리스트를 필터링
    • @PostFilter: 메서드 실행 후 반환된 결과 리스트를 필터링

 

2.1 사전 필터링

  • 메서드가 실행되기 전에, 메소드에 전달된 인수 중에서 특정 권한에 맞는 데이터만 메서드로 전달되도록 필터링하는 작업
  • 메서드가 실행되기 전에 입력 데이터 중에서 사용자가 접근할 수 있는 데이터만 메서드로 전달됨
  • 파라미터나 반환 결과값이 규칙을 준수하지 않아도 메서드 호출은 그대로 발생
    • 예외를 던지지 않음
    • 단, 조건에 맞지 않는 파라미터나 반환 결괏값을 필터링함
    • 필터링의 개념이기 때문에 컬렉션이나 배열에서만 활용 가능

 

  • 메서드가 구현하는 비즈니스 로직과 권한 부여 규칙을 분리할 수 있다는 장점이 있음
  • @PreFilter 어노테이션은 메서드에 전달되는 컬렉션이나 배열 등의 데이터에 대해 필터링을 적용하여, 특정 조건을 만족하는 데이터만 메서드에 전달
    • Spring Expression Language(SpEL)을 사용해 필터링 조건을 설정할 수 있으며, 필터링된 데이터만 메서드 내부에서 처리

 

 

 

주의: 필터링 개념이기 때문에 컬렉션은 추가/삭제가 가능한 MutableList 형태여야 함

 

2.2 사후 필터링

  • 메서드가 실행된 후, 반환된 결과 데이터 중에서 사용자 권한에 맞는 데이터만 필터링하여 반환하는 작업
  • 메서드가 실행된 후 결괏값이 클라이언트로 반환되기 전에 필터링이 이루어져, 사용자가 접근할 수 없는 데이터는 결괏값에서 제거
    • 민감한 데이터나 접근이 제한된 데이터를 클라이언트에 노출하지 않도록 처리 가능

 

  • @PostFilter 어노테이션은 메서드가 반환하는 컬렉션이나 배열 등의 데이터에 대해 필터링을 적용
    • ex) ReactJS로 구현된 프런트엔드와 스프링으로 구현된 백엔드가 서로 연결되어 있다고 가정했을 때 프런트에서는 로그인된 사용자에 대한 데이터만 조회해야 하는 상황이지만 어떤 데이터가 존재하는지 모르는 상황
    • 이에 따라 로그인된 정보를 백엔드로 전달하면 백엔드에서 알아서 필터링하여 프런트로 전달


 

주의: @PostFilter를 사용하기 위해서는 인증된 사용자 정보와 전체 리스트가 필요하기 때문에 findAll()과 같은 메서드로 전체 리스트를 가져오게 될 텐데, 실무 수준에서는 데이터 양이 엄청날 수 있음

  • 경우에 따라 OOM(Out Of Memory)가 발생할 수 도 있고 성능 관점에서 매우 비효율적인 방법

 

참고

https://fastcampus.co.kr/classroom/240071

반응형