ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [스프링 시큐리티] 권한 설정과 표현식
    강의노트/스프링 시큐리티 2020. 9. 10. 21:27

    권한 설정

    선언적 방식

    Url을 이용한 방식

    protected void configure(HttpSecurity http) throws Exception {
        http
            .antMatchers("/users/**")
            .authorizeRequests()
                .antMatchers("/shop/login", "/shop/users/**").permitAll()
                .antMatchers("/shop/mypage").hasRole("ROLE_USER")
                .antMatchers("/shop/admin/pay").access("hasRole('ROLE_ADMIN')")
                .antMatchers("/shop/admin/**").access("hasRole('ROLE_ADMIN') or hasRole('ROLE_SYS')")
                .anyRequest().authenticated()
    }

    설정 시 구체적인 경로가 먼저 오고 그것보다 큰 범위의 경로가 뒤에 오도록 해야 한다.

    예를 들어 위에서 /shop/admin/** antMatchers가 /shop/admin/pay antMatchers 위에 위치하게 된다면 원래는 /shop/admin/pay 리소스는 ROLE_ADMIN만 접근가능하지만 /shop/admin/**에서 통과되기 때문에 ROLE_SYS권한을 가진 계정도 /shop/admin/pay 리소스에 접근 가능해진다.

    Method를 이용한 방식

    @RestController
    public class UserController {
        @PreAuthorize("hasRole("ROLE_USER")")
        @GetMapping("/api/v1/users")
        public List<User> findUsers() {
            ...
        }
    }

    동적 방식 - DB 연동 프로그래밍

    • Url을 이용한 방식
    • Method를 이용한 방식

    표현식

    메소드 동작
    authenticated() 인증된 사용자의 접근을 허용
    fullyAuthenticated() 인증된 사용자의 접근을 허용, rememberMe 인증 제외
    permitAll() 무조건 접근을 허용
    denyAll() 무조건 접근을 허용하지 않음
    anonymous() 익명 사용자의 접근 허용
    rememberMe() remember-me 인증된 사용자의 접근 허용
    access(String) 주어진 SpEL 표현식의 평가 결과가 true인 경우 접근 허용
    hasRole(String) 사용자가 주어진 역활이 있으면 접근 허용
    hasAuthority(String) 사용자가 주어진 권한이 있으면 접근 허용
    hasAnyRole(String) 사용자가 주어진 역활 중 어떤 것이라도 있으면 접근 허용
    hasAnyAuthority(String) 사용자가 주어진 권한 중 어떤 것이라도 있으면 접근 허용
    hasIpAddress(String) 주어진 IP로부터 요청이 왔다면 접근 허용
    import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    import org.springframework.security.core.session.SessionRegistry;
    import org.springframework.security.core.session.SessionRegistryImpl;
    import org.springframework.security.web.session.HttpSessionEventPublisher;
    
    @Configuration
    @EnableWebSecurity  // 웹 보안을 활성화 시키는 어노테이션
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
        // 사용자를 생성하고 권한을 설정하는 클래스
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            // 패스워드 앞에 스프링 시큐리티 5버젼 이후 부터 암호화 방식을 prefix로 설정해야함
            // noop : 암호화 알고리즘을 사용하지 않음
            auth.inMemoryAuthentication().withUser("user").password("{noop}1111").roles("USER");
            auth.inMemoryAuthentication().withUser("sys").password("{noop}1111").roles("SYS");
            auth.inMemoryAuthentication().withUser("admin").password("{noop}1111").roles("ADMIN");
            // ADMIN > SYS > USER의 권한 체계를 가진 상태에서 ADMIN 권한을 가진 사용자가 SYS, USER 권한이 필요한 리소스에 접근하기 위해서는 해당 권한들을 모두 설정 필요
            // auth.inMemoryAuthentication().withUser("admin").password("{noop}1111").roles("ADMIN", "SYS", "USER");
        }
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
    
            http
                .authorizeRequests()
                .antMatcher("/user").hasRole("USER")        // /user 리소스 접근 시 USER Role을 가져야 통과됨
                .antMatcher("/admin/pay").hasRole("ADMIN")  // /admin/pay 리소스 접근 시 ADMIN Role을 가져야 통과됨
                .antMatcher("/admin/**").access("hasRole('ADMIN') or hasRole('SYS')")        // /admin 이하 리소스 접근 시 ADMIN 또는 SYS Role을 가져야 통과됨
                .anyRequest().authenticated();
    
            http
                .formLogin();
        }
    }

    인프런 스프링 시큐리티 - Spring Boot 기반으로 개발하는 Spring Security 강좌 참조

    댓글

Designed by Tistory.