사용자가 늘어나고 서비스가 복잡해질수록 ‘누가 무엇을 할 수 있는가’에 대한 관리는 기하급수적으로 어려워집니다. 단순히 로그인 여부만 체크하는 수준을 넘어, 부서별, 직급별, 혹은 특정 프로젝트별로 세밀하게 권한을 제어해야 하는 상황이 오기 마련이죠. 오늘은 Spring Security의 정수인 **RBAC(Role-Based Access Control)**을 활용해, 어떠한 비즈니스 요구사항에도 대응할 수 있는 강력한 보안 아키텍처를 설계하는 법을 다뤄보겠습니다.

[그림 1] 계층화된 보안 구역과 역할을 통한 접근 제어(RBAC)의 개념
1. Spring Security의 심장: 필터 체인(Filter Chain)의 이해
RBAC을 깊이 있게 다루기 전에, 반드시 이해해야 할 것이 바로 **Security Filter Chain**입니다. Spring Security는 서블릿 필터를 기반으로 동작하며, 요청이 컨트롤러에 도달하기 전 수많은 ‘검문소’를 거치게 됩니다.

[그림 2] 인증과 인가가 이루어지는 Spring Security의 핵심 필터 흐름
권한 체크의 핵심은 마지막 단계인 `FilterSecurityInterceptor`에서 일어납니다. 여기서 현재 사용자의 권한(`GrantedAuthority`)과 해당 API가 요구하는 권한이 일치하는지 최종 판결을 내립니다. 이 흐름을 이해해야만 커스텀 필터를 만들거나 권한 로직을 디버깅할 때 미로에 빠지지 않습니다.
2. RBAC 설계의 핵심: Role vs Authority
많은 개발자가 혼동하는 개념이 바로 **Role**과 **Authority**입니다.
– **Role (역할)**: ‘ADMIN’, ‘MANAGER’, ‘USER’와 같은 추상적인 개념입니다. 통상 `ROLE_` 접두사를 붙여 관리합니다.
– **Authority (권한)**: ‘READ_POST’, ‘DELETE_USER’와 같이 실제 액션을 수행할 수 있는 구체적인 권한입니다.
엘리트 설계에서는 이 둘을 분리합니다. 사용자는 ‘역할’을 가지고, 그 ‘역할’은 여러 개의 ‘권한’을 포함하는 구조(N:M)를 가져야 요구사항 변화에 유연하게 대처할 수 있습니다.
3. 권한 매트릭스 설계와 DB 구조

[그림 3] 역할별 허용되는 작업 범위를 정의한 권한 매트릭스 예시
위 매트릭스처럼 설계를 마쳤다면, 이를 DB로 옮길 때는 최소 5개의 테이블이 필요합니다: `User`, `Role`, `Authority`, `User_Role(매핑)`, `Role_Authority(매핑)`. 이 구조를 통해 ADMIN 코드 한 줄 수정 없이 DB 데이터만으로 특정 직책의 권한을 즉시 변경할 수 있는 ‘운영의 묘’를 발휘할 수 있습니다.
4. 실전 코드: Method Level Security의 활용
설정 파일에서 URL 기반으로 권한을 막는 것도 좋지만, 비즈니스 로직에 더 가깝게 권한을 제어하려면 **Method Security**를 사용해야 합니다.
@Service
public class PostService {
@PreAuthorize("hasRole('ADMIN') or hasAuthority('DELETE_POST')")
public void deletePost(Long postId) {
// 인가된 사용자만 진입 가능
postRepository.deleteById(postId);
}
}
`@PreAuthorize` 어노테이션을 활용하면 SpEL(Spring Expression Language)을 통해 더욱 복잡한 권한 로직(예: 본인이 쓴 글만 삭제 가능)을 선언적으로 구현할 수 있습니다.
마치며: 보안은 설계 단계에서 완성됩니다
단순히 ‘돌아가게 만드는’ 보안은 취약점을 남기기 마련입니다. 서비스의 성장을 고려한다면 초기부터 명확한 RBAC 전략을 수립해야 합니다. 오늘 다룬 필터 체인의 원리와 역할-권한 분리 전략을 프로젝트에 적용해 보시기 바랍니다. 견고한 보안은 훌륭한 백엔드 개발자의 가장 강력한 무기입니다.