네이버 카페를 가입해 본적이 있는 사람들은 처음 글을 쓸때 등업이 되지 않아 게시판에 글을 올리지 못한 경험이 있을 것이다. 씨앗 레벨은 인사글만 작성가능하고 새싹 레벨은 자유 게시글 나무 레벨은 질문게시글까지 작성할 수 있을때 나무 레벨은 인사글 자유게시글 모두 작성이 가능 하다. 이처럼 특정 url로 접근할 수 있는 role이 여러개일 때 계층 권한은 어떻게 설정하는지 알아보자
1-1. 페이지 권한

시큐리티 필터체인을 보면 admin page, manage page, user page 에 권한을 두었다. 여기서 우리가 원하는 것은 admin은 manage, user 페이지에 접근 할 수 있어야 하고 manager는 user 페이지에 접근 할 수 있어야 한다.
1-2. RoleHierarchy
스프링 시큐리티에서는 RoleHierarchy 인터페이스를 지원한다. 이 기능은 Role 간의 계층 구조를 설정하여 상위 권한이 하위 권한의 역할을 포함하도록 해 준다.
@Bean
public RoleHierarchy roleHierarchy(){
return RoleHierarchyImpl.fromHierarchy("""
ROLE_ADMIN > ROLE_MANAGER
ROLE_MANAGER > ROLE_USER
""");
}
자 코드를 살펴보면 직관적으로 누가 더 높은 권한을 가지는지 알 수 있다. 단순 String 으로 어떻게 권한의 계층이 생기는지 한 번 알아보자
1-3.RoleHierarchyImpl

RoleHierarchyImpl 은 RoleHierarchy 인터페이스를 구현받고 또 fromHierarchy 를 타고 들어가보면 최종적으로 buildRolesReachableInOneStepMap(String hierarchy) 메서드를 사용한다.

코드를 확대해서 살펴보면 우리가 작성한 String 을 가지고 split("\n") 줄바꿈을 기준으로 먼저 구분한다. 그 후 나누어진 String 을 split("\\s+>+\\s") 으로 Role들을 나누어 왼쪽에 있던 Role이 더 큰 권한을 가지게 해 주는 것이다. 이처럼 정규식이 메서드에 설정되어 있기에 잘 확인한 후 코드를 작서성해야한다.
2. 리펙토링
@Bean
public RoleHierarchy roleHierarchy(){
return RoleHierarchyImpl.fromHierarchy("""
ROLE_ADMIN > ROLE_MANAGER
ROLE_MANAGER > ROLE_USER
""");
}
코드를 다시 살펴보면 조금 아쉬운 점이 있다. 중간에 Role이 추가 될때 마다 하드코딩으로 String 을 작성해 줘야 한다는 것이다. 그렇다면 개발자가 실수를 할 가능성이 굉장히 많아진다. 그래서 나는 enum의 상수 인덱스를 활용하기로 했다.
@Bean
public RoleHierarchy roleHierarchy(){
Role[] roleList = Role.values();
StringBuilder hierarchy = new StringBuilder();
for(int i = 0; i < roleList.length - 1; i++) {
hierarchy
.append(roleList[i].getRoleName())
.append(" > ")
.append(roleList[i + 1].getRoleName())
.append("\n");
}
return RoleHierarchyImpl.fromHierarchy(hierarchy.toString());
}

이런식으로 가장 높은 권한을 가진 Role부터 상수를 선언한다면 더이상 Role 이 추가 되거나 삭제되어도 roleHierarchy() 메서드를 더이상 수정 할 필요가 없어진다.
3. 생각해 볼점.
만약 새로운 Role이 추가된다면 시큐리티에 새로운 계층구조를 저장하기 위해 roleHierarchy()메서드를 재 실행해야 할것이다. 또한 member가 가지는 Role이 여러개일 경우 데이터베이스에 Role 테이블을 미리 만들어 놔야 하는데 새로운 Role이 추가될때 데이터베이스에 새로운 Role을 저장하는 로직도 생각해봐야 할것같다.
'스프링 > security' 카테고리의 다른 글
| JWT의 동작원리 (0) | 2024.09.12 |
|---|---|
| 스프링 시큐리티 JWT란 무엇일까? 왜 사용할까? (0) | 2024.09.11 |
| 메서드 권한 설정 (0) | 2024.08.09 |