(spring security) 권한 부여 구성

jint·2024년 10월 27일

보안

목록 보기
8/15

인증 필터를 통해 인증이 완료되면 UserDetails가 SpringContext에 저장하고

요청을 권한 부여 필터에 위임한다.

권한 부여 필터는 보안 컨텍스트를 통해 UserDetails에 접근해 UserDetails의 메서드인

getAuthorities를 호출해 이용권한이 있으면 controller에 요청을 보낸다.

MVC 선택기로 권한 부여 요청

POST,PUT,DELETE을 쓰기 위해서 예제이기 때문에 csrf토큰 보호를 비활성화한다.

@RestController
public class TestController {
    @PostMapping("/a")
    public String postEndpointA() {
        return "postEndpointA";
    }

    @GetMapping("/a")
    public String getEndpointA() {
        return "getEndpointA";
    }
}
@Configuration
public class ProjectConfig {
    @Bean
    public UserDetailsService userDetailsService() {
        UserDetailsManager manager = new InMemoryUserDetailsManager();

        UserDetails user = User.withUsername("john")
                .password("12345")
                .authorities("READ")
                .build();

        manager.createUser(user);

        return manager;
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return NoOpPasswordEncoder.getInstance();
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
		    http.httpBasic(Customizer.withDefaults())
                .csrf(AbstractHttpConfigurer::disable);
        http.authorizeHttpRequests(
                authorizeRequests -> authorizeRequests
				                .requestMatchers(HttpMethod.GET, "/a")
                        .authenticated()
                        .requestMatchers(HttpMethod.POST, "/a")
                        .permitAll()
                        .anyRequest()
                        .denyAll());
        return http.build();
    }
}

WebSecurityConfigurerAdapter가 deprecated되었기 때문에 SecurityFilterChain을 사용해서 구성

/a에 대한 GET은 authenticated()로 인증이 필요한 엔드포인트

/a에 대한 POST요청은 permitAll로 인증이 필요없는 엔드포인트

그외 나머지 요청은 denyAll로 전부 접근할 수 없는 엔드포인트로 구성.

권한에 대한 조건을 지정하기 위한 방법.

위 예제를 바탕으로 POST요청을 “WRITE”권한이 있는 사람만 접근할 수 있도록 바꾸기.

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
		    http.httpBasic(Customizer.withDefaults())
		        .csrf(AbstractHttpConfigurer::disable);
        http.authorizeHttpRequests(
                authorizeRequests -> authorizeRequests
				                .requestMatchers(HttpMethod.GET, "/a")
                        .authenticated()
                        .requestMatchers(HttpMethod.POST, "/a")
                        .hasAuthority("WRITE")
                        .anyRequest()
                        .denyAll());
                        
        return http.build();
    }

hasAuthority는 하나의 권한만 매개변수로 받을 수 있다.

여러개의 권한을 체크하기 위해서는 hasAnyAuthority를 쓴다.

spEL식을 이용하는 access를 사용할 수 도 있는데 매우 유연하기 때문에 어떤 조건이든 정의할 수 있다는 장점이 있지만 코드를 읽고 이해하기 어려워지기 때문에 위 2개를 써서 조건을 표현할 수 없을 때만 이용한다.

requestMatcher는 mvcMatcher, antMatcher,regexMatcher가 deprecated되면서 등장한 선택기지만

기본으로 Spring Mvc라면 mvcMatcher처럼 작동한다.

특별히 정규식을 써야한다면

.requestMatchers(regexMatcher(정규식))

이런식으로 사용할 수 있다.

antMatcher mvcMatcher와는 다르게 마지막 경로 뒤 /를 다른 요청으로 보기 때문에 주의가 필요하다.

mvcMatcher는 spring mvc와 경로 처리 및 작업 매핑 방식이 동일하기 때문에 spring mvc를 사용중이라면

antMatcher보다 mvcMatcher를 쓰는 것이 권장된다.

정규식 생성자

https://regexr.com

사용자 역활을 기준으로 한 접근제한

사용자 역활을 기준으로 접근 제한을 하기 위해서는 권한과 차이를 나타내기위해

접두사 ROLE_로 시작해야한다.

위 예제를 바탕으로 /a GET요청을 ADMIN역활을 가진사람만 접근가능하도록 바꾸기

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests(
                authorizeRequests -> authorizeRequests
				                .requestMatchers(HttpMethod.GET, "/a")
                        .hasRole("ADMIN")
                        .requestMatchers(HttpMethod.POST, "/a")
                        .hasAuthority("WRITE")
                        .anyRequest()
                        .denyAll());

        http.httpBasic(Customizer.withDefaults())
                .csrf(AbstractHttpConfigurer::disable);
        return http.build();
    }

0개의 댓글