springframework/시작하자SpringSecurity

11. 권한 설정과 표현식

Jungsoomin :) 2020. 9. 21. 06:45

인가 API의 권한 설정방식과 Mapping 방식

 

인가 API권한 설정에는 2가지가 있다.

  • 선언적 방식 

  • 동적방식 : DB 연동 

각 방식들은 다시 2가지 방식을 가진다.

  1. URL

  2. Method

지금은 , 선언적 방식과 URL 방식을 사용한다.

 


권한 설정 API

 

  1. antMatcher(url) : 경로에 대한 Ant 패턴, 해당 경로에 대한 권한여부를 검사하게 한다. 사용하지 않을시 모든 요청에 대해 권한여부를 검사한다.

  2. authorizeRequest() : 인가 요청

  • antMatchers(url ...) 이후에 인가 API들이 추가 된다.

주의할 점은, 코드는 위에서 아래로 해석하므로 반드시 구체적인 경로가 먼저 오고 뒤에 넒은 범위의 경로가 와야한다. 

이후 http .anyRequest().authenticated() 를 사용하여 다른 자원들에 대한 인증 여부 또한 결정할 수 있다.


인가 API의 표현식

 

  1. authenticated() : 인증된 사용자의 접근 허용

  2. fullyAuthenticated() : RememberMe 기능을 제외한 인증된 사용자 접근 허용

  3. permiAll() : 모든 접근 허용

  4. denyAll() : 모든 접근 불가

  5. anonymous() : 익명 사용자만의 접근을 허용

  6. rememberMe() : RemeberMe 기능으로의 접근만을 허용

  7. access(String) : SpEL 의 평가 결과가 true라면 접근 허용

  8. hasRole(String) : 사용자가 주어진 역할이 있다면 접근허용, 매개값에 "ROLE"적으면 예외 발생

  9. hasAuthority(String) : 사용자가 주어진 권한이 있다면 접근 허용, 매개값에 "ROLE"적지않으면 예외 발생

  10. hasAnyRole(String ...) : 여러개의 역할하나라도 있다면 접근 허용, 매개 값에 "ROLE"적으면 예외 발생

  11. hasAnyAuthority(String ...) : 여러개의 권한하나라도 있다면 접근 허용, 매개 값에 "ROLE"적지않으면 예외 발생

  12. hasIpAddress(String) : 주어진 IP로 요청이 오면 접근 허용


선언적 방식과 , URL 방식의 코드

사용자를 생성하는 방식configure(AuthenticationManagerBuilder) 메서드의 재정의 이다.

  1. auth.inMemoryAuthentication() : 메모리방식으로 사용자 생성

  • withUser(username) : 생성할 유저 이름

  • password(password) : 생성할 암호, 접두사 {prefix} 를 붙여 암호화 알고리즘을 정해야 한다. 

  • roles(ROLE) : 주어질 권한

권한 부여시에 경로설정 해당 경로에 대한 권한을 가진 사용자만이 접근 할 수 있으므로, 자식 권한 들에 대해서 모두 권한 설정을 해줘야만 한다.

 

권한 계층 설정시 이런 설정은 쓰지않아도 된다.

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().withUser("user").password("{noop}1111").roles("USER");//메모리 방식으로 사용자를 생성하겠다.
        auth.inMemoryAuthentication().withUser("sys").password("{noop}1111").roles("SYS","USER");
        auth.inMemoryAuthentication().withUser("admin").password("{noop}1111").roles("ADMIN","SYS","USER");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
//                .antMatcher("")
                .authorizeRequests()
                .antMatchers("/user").hasRole("USER")// 해당경로에 대해 USER 권한심사를 하겠다.
                .antMatchers("/admin/pay").hasRole("ADMIN")// 해당경로에 대해 ADMIN 권한심사를 하겠다.
                .antMatchers("/admin/**").access("hasRole('ADMIN') or hasRole('SYS')")//해당 경로들에 대해 SpEL 이 true 인지 권한심사를 하겠다.
                .anyRequest()//모든 요청에 대해
                .authenticated();//인증된 사용자 만의 접근을 허용한다.

        http
                .formLogin();//폼 로그인 방식을 사용하겠다.
    }
}

실제로 서비스가 가능할까.

선언적 방식메모리에 유저정보를 등록하는 방서비스에 적합하지 않다.

 

오히려 TestCase에 알맞다.

 

실제로 서비스하기 위해서는 다음 방식이 알맞다.

 

  1. 동적 방식 : DB 를 이용한 연동방식을 사용한다.

  2. 권한정책 : 즉각적으로 인가 정책과 처리가 이루어지도록하는 기능을 사용한다.