Spring-Security-2

akanana·2023년 2월 22일
0

Spring-Security

목록 보기
3/8

목표

  • 권한 추가 및 설정

페이지별로 권한을 제한하고 싶어요


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 지정

이제 권한별로 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"
};

SecrityFilter 설정

이제 각 정보들을 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());
...
}

0개의 댓글