흔히 RESTful API 설계 방식에서 슬래시(/)
를 통해 리소스 구조를 표현하는데 리눅스의 파일 시스템에서도 같은 방식으로 구분을 하고 있다.
URI에서 슬래시는 구조를 표현하는 중요한 역할을 하고 있기 때문에, URI맨 뒤쪽에 넣는다면 혼동이 생길 수 있다.
Spring Security에서 기본적으로 사용하는 antMatchers
는 URI 맨 뒤에 슬래시가 붙어있어도 블랙리스트 방식
으로 한다면 403에러가 아닌 200 OK 로 반응한다.
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic().disable()
.csrf().disable()
.authorizeRequests()
.antMatchers(GET, "/api/members").authenticated()
.anyRequest().permitAll();
}
}
위의 설정은 /api/members
로 오는 GET
방식의 요청으로만 허용되도록 설정되어 있다.
@RestController
class TestApi {
@GetMapping("/api/members/")
public String greeting() {
return "Hello";
}
}
이렇게 테스트 해본다면 http 응답 200으로 잘 작동되는 것을 알 수 있다.
즉, 보안에 문제가 발생한다
이 문제를 방지하기 위해서는 화이트리스트 기법
을 사용하는 모든 엔드포인트를 인증필요
상태로 관리하고 인증없이 허용
할 몇몇 엔드포인트만을 작성해야한다.
또한, 스프링 시큐리티에서도 화이트리스트 방식을 권장하고 있다.
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic().disable()
.csrf().disable()
.authorizeRequests()
.antMatchers(GET, "/api/members").permitAll()
.anyRequest().authenticated();
}
}
만약 꼭 블랙리스트 방식
으로 코드를 작성해야 한다면
아래와 같은 두가지 방법이 존재한다.
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic().disable()
.csrf().disable()
.authorizeRequests()
.antMatchers(GET, "/api/members/**").authenticated()
.anyRequest().permitAll();
}
}
이렇게 한다면 antMatchers로도 /api/members/로 접근할려고 해도 403에러가 발생한다.
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic().disable()
.csrf().disable()
.authorizeRequests()
.mvcMatchers(GET, "/api/members").authenticated()
.anyRequest().permitAll();
}
}
이렇게 해도 /api/members/로 접근할려고 해도 403에러가 발생하기 때문에 보안 문제를 보완 할 수 있다.