유튜브 "개발자 유미"님 강의를 듣고 정리한 내용입니다.
특정 url로 접근할 수 있는 Role이 여러 개일 때, 계층 권한을 설정할 수 있다.
Security Config에서 SecurityFilterChain 빈 등록 시에 다음과 같이 인가 작업을 했다고 가정하자.
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((auth) -> auth
.requestMatchers("/login").permitAll()
.requestMatchers("/").hasAnyRole("A", "B", "C")
.requestMatchers("/manager").hasAnyRole("B", "C")
.requestMatchers("/admin").hasRole("C")
.anyRequest().authenticated()
);
http
.formLogin((auth) -> auth
.loginPage("/login")
.loginProcessingUrl("/loginProc")
.permitAll());
return http.build();
}
이와 같이 설정 했을 때의 권한은 C > B > A 순 이다. (높은 권한이 큰 쪽)
"/"라는 url에 대해서 "A"에 대한 권한만 설정해주어도 "A"보다 높은 권한인 "B", "C"도 접근할 수 있도록 하고 싶다.
위 상황에서 계층 권한을 사용할 수 있다.
RoleHierarchy 클래스 참고: https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/access/hierarchicalroles/RoleHierarchyImpl.html#fromHierarchy(java.lang.String)
메서드 사용 참고 : https://github.com/spring-projects/spring-security/blob/main/core/src/test/java/org/springframework/security/access/hierarchicalroles/RoleHierarchyImplTests.java
@Bean
public static RoleHierarchy roleHierarchy() {
return RoleHierarchyImpl.fromHierarchy("""
ROLE_C > ROLE_B
ROLE_B > ROLE_A
""");
}
계층 권한 빈을 다음과 같이 등록할 수 있다.
기존에 사용하던 setHierarchy() 메서드는 deprecated 되었으므로, 대신 static 메서드인 fromHierarchy() 메서드를 사용한다.
큰따옴표를 연속해서 세 개 찍으면("""), 이스케이프 문자 없이 word 문서를 사용하는 것처럼 엔터로 줄바꿈하여 String을 쓸 수 있다.
한 줄에 두 권한 간의 비교를 하도록 한다. ROLE_ 접두사를 반드시 붙여주어야 한다.
이렇게 C > B > A 의 계층 권한이 설정되었다. 이제 필터 체인 빈의 인가 작업 부분을 수정할 수 있다.
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((auth) -> auth
.requestMatchers("/login").permitAll()
.requestMatchers("/").hasRole("A")
.requestMatchers("/manager").hasRole("B")
.requestMatchers("/admin").hasRole("C")
.anyRequest().authenticated()
);
http
.formLogin((auth) -> auth
.loginPage("/login")
.loginProcessingUrl("/loginProc")
.permitAll());
return http.build();
}
설정해둔 계층 권한 빈을 보고 특정 url에 낮은 계층의 권한이 인가된 경우에는, 그보다 높은 계층 권한에게도 자동으로 인가가 된다.