
user page에는 user 이상의 권한,
manager page에는 manager 이상의 권한,
admin page에는 admin 이상의 권한이 필요하게 만들고싶다
이때 Spring Security의 ROLE 기능을 사용할 수 있다
SecurityConfig.java
...
@Bean
public static PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
@Bean
public UserDetailsService userDetailsService(){
UserDetails banana = User.builder()
.username("banana")
.password(passwordEncoder().encode("banana"))
.roles("USER")
.build();
UserDetails furu = User.builder()
.username("furu")
.password(passwordEncoder().encode("furu"))
.roles("MANAGER")
.build();
UserDetails admin = User.builder()
.username("admin")
.password(passwordEncoder().encode("admin"))
.roles("ADMIN")
.build();
List<UserDetails> list = new ArrayList<>();
list.add(banana);
list.add(furu);
list.add(admin);
return new InMemoryUserDetailsManager(list);
}
...
총 3개의 유저를 만들었다
이제 권한별로 url을 지정해보자
private static final String[] AUTH_WHITELIST = {
"/", "/login", "/logout", "/signup", "/home"
};
private static final String[] AUTH_USER_LIST = {
"/user"
};
private static final String[] AUTH_MANAGER_LIST = {
"/manager"
};
private static final String[] AUTH_ADMIN_LIST = {
"/admin"
};
이제 각 정보들을 SecurityFilter에 추가하였다
AuthorityAuthorizationManager<RequestAuthorizationContext> userAuth
= AuthorityAuthorizationManager.<RequestAuthorizationContext>hasRole("USER");
AuthorityAuthorizationManager<RequestAuthorizationContext> managerAuth
= AuthorityAuthorizationManager.<RequestAuthorizationContext>hasRole("MANAGER");
AuthorityAuthorizationManager<RequestAuthorizationContext> adminAuth
= AuthorityAuthorizationManager.<RequestAuthorizationContext>hasRole("ADMIN");
http.csrf().disable()
.authorizeHttpRequests(authorize -> authorize
// .anyRequest().permitAll()
.requestMatchers(AUTH_WHITELIST).permitAll()
.requestMatchers(AUTH_USER_LIST).access(userAuth)
.requestMatchers(AUTH_MANAGER_LIST).access(managerAuth)
.requestMatchers(AUTH_ADMIN_LIST).access(adminAuth)
)
.formLogin();
타입추론
jdk10부터 타입추론을 통하여 java 객체 선언이 가능하다
위 코드또한 다음처럼 수정하여 가독성을 향상시킬 수 있다.var userAuth = AuthorityAuthorizationManager.<RequestAuthorizationContext>hasRole("USER"); var managerAuth = AuthorityAuthorizationManager.<RequestAuthorizationContext>hasRole("MANAGER"); var adminAuth = AuthorityAuthorizationManager.<RequestAuthorizationContext>hasRole("ADMIN");
위처럼 동작시, ROLE_MANAGER 권한을 가진 유저는 manager.html에만 접근 가능할 뿐, user.html에는 접근이 불가능하다
이를 위해서 권한을 상속해주었다
@Bean
public RoleHierarchy roleHierarchy(){
String role = "ROLE_ADMIN > ROLE_MANAGER > ROLE_USER";
RoleHierarchyImpl r = new RoleHierarchyImpl();
r.setHierarchy(role);
return r;
}
...
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{
...
userAuth.setRoleHierarchy(roleHierarchy());
managerAuth.setRoleHierarchy(roleHierarchy());
adminAuth.setRoleHierarchy(roleHierarchy());
...
}