[JAVA] 69. 역할(Role) 체크

윤설안's avatar
Jul 27, 2025
[JAVA] 69. 역할(Role) 체크

1. Spring Security는 "ROLE_" prefix가 필수다

Spring Security는 내부적으로 권한(Role)을 체크할 때 항상 "ROLE_" 를 붙여서 비교한다.
  • 예를 들어, 다음과 같은 코드가 있다고 하자:
@PreAuthorize("hasRole('ADMIN')")
위 코드는 내부적으로 "ROLE_ADMIN"과 비교한다.
즉, 사용자의 역할 정보가 "ADMIN"만 있다면 접근 거부됨.
"ROLE_ADMIN"이어야만 통과된다.

2. User 클래스에서 Role 변환 구현

@Override public Collection<? extends GrantedAuthority> getAuthorities() { Collection<GrantedAuthority> authorities = new ArrayList<>(); for (String role : roles.split(",")) { authorities.add(() -> "ROLE_" + role.trim()); // Spring Security가 인식 가능하도록 ROLE_ 을 명시적 추가 } return authorities; }
  • roles 필드 예시: "USER", "ADMIN,USER"처럼 저장됨
  • roles 문자열을 쉼표(,) 기준으로 분리하여 각각의 역할을 순회한다.
  • 위 구현 덕분에 USERROLE_USER, ADMINROLE_ADMIN으로 변환됨
  • Security가 인식 가능한 형태로 권한 제공됨

3. 여러 권한을 주는 것이 좋은 이유

ADMINUSER 기능을 포함해야 하므로, ADMIN 유저에게 USER, ADMIN 두 개의 역할을 부여하면 계층적 역할 관리가 가능하고 코드 재사용성과 유지보수성이 높아진다.

1. 권한의 계층적 구조 (Role Hierarchy)

  • 일반적으로 관리자(ADMIN)는 사용자(USER)의 기능을 포함해서 사용할 수 있어야 해요.
  • 예: 관리자도 게시글을 작성하고 댓글을 달 수 있어야 하는데, 이건 USER 권한이 있어야 가능하죠.
  • 따라서 ADMIN만 있으면 USER 기능을 못하게 막히는 일이 생겨요.
  • roles = "USER,ADMIN"로 설정하면 둘 다 허용되어 이 문제가 해결돼요.

2. 코드 중복 방지

  • ADMIN 권한이 USER 권한을 포함하면, /user/** 경로에 대해 따로 ADMIN 허용 코드를 쓰지 않아도 돼요.
  • 즉, 다음처럼 안 써도 됨:
    • .requestMatchers("/user/**").hasAnyRole("USER", "ADMIN") // 이렇게 안 써도 됨

3. 유지보수 용이

  • 이후 권한이 더 늘어나거나, 정책이 바뀌더라도 계층 구조가 잘 되어 있으면 수정할 부분이 적어요.
  • 예: MODERATOR, SUPER_ADMIN 등 추가될 때, 기본 권한을 구성만 잘 해두면 영향 최소화됨.
Share article

An's Blog