API에 권한 기능이 없으면, 누구나 회원 정보를 조회하고 수정할 수 있기 때문에, 인증된 사용자만 API를 사용할 수 있도록 설정해야 한다. 이를 위해 스프링에서는 Spring Security를 제공한다. Spring Security를 통해 인증(Authentication)과 권한 부여(Authorization)를 쉽게 설정할 수 있다.
Spring Security는 스프링의 DispatcherServlet
앞단에 Filter 형태로 위치한다. 클라이언트가 API에 요청할 때, Dispatcher
로 넘어가기 전에 Spring Security의 필터가 요청을 가로채서 클라이언트의 권한을 확인한다. 만약 권한이 없다면, 인증 요청 화면으로 리다이렉트되거나, 오류 메시지를 반환하게 된다.
Spring Security에서 사용하는 필터는 종류가 매우 많다. 그중 대표적인 필터가 UsernamePasswordAuthenticationFilter
로, 클라이언트가 리소스에 접근 권한이 없을 때 처리해주는 필터이다.
API 인증 및 권한 부여를 위한 기본적인 작업 순서는 아래와 같다.
ROLE_USER
권한 부여ROLE_USER
권한을 가진 회원만 접근 가능하도록 설정위와 같은 구성으로 API에 접근할 수 있도록 하면, JWT 보안 토큰을 통해 사용자가 인증되었는지, 권한이 있는지를 Spring Security에서 확인하고 리소스 요청을 처리할 수 있게 된다.
서버의 보안을 설정하기 위해서는 Spring Security의 Configuration을 작성해야 한다. 아래는 Spring Security 설정의 예제 코드다. 이 코드에서는 인증되지 않은 요청에 대한 접근 제한을 설정하고, ROLE_USER
권한을 가진 사용자만 API에 접근할 수 있도록 구성하고 있다.
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic().disable() // REST API이므로 기본 설정 사용 안 함. 비인증 시 로그인 폼 화면으로 리다이렉트되는 기본 설정을 비활성화
.cors().configurationSource(corsConfigurationSource())
.and()
.csrf().disable() // REST API이므로 CSRF 보안이 필요 없으므로 disable 처리
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) // JWT 토큰으로 인증하므로 세션은 필요 없으므로 생성하지 않음
.and()
.authorizeRequests() // 다음 요청들에 대한 권한 체크
.antMatchers("/*/signin", "/*/signup", "/social/**").permitAll() // 회원가입 및 인증 URL은 누구나 접근 가능
.antMatchers(HttpMethod.GET, "/home/**").permitAll() // "home"으로 시작하는 GET 요청 리소스는 누구나 접근 가능
.anyRequest().hasRole("USER") // 그 외 나머지 요청은 모두 인증된 회원만 접근 가능
.and()
.addFilterBefore(new JwtAuthenticationFilter(jwtTokenProvider), UsernamePasswordAuthenticationFilter.class); // JWT 토큰 필터를 UsernamePasswordAuthenticationFilter 앞에 추가
}
Spring Security는 스프링 애플리케이션에서 인증과 권한 부여를 쉽게 구현할 수 있는 프레임워크다. 이를 통해 보안을 자체적으로 구현할 필요 없이, 필요한 기능을 간편하게 적용할 수 있다. Spring Security를 설정하여 JWT 토큰 기반 인증을 사용하면 API의 접근을 제한할 수 있으며, 이를 통해 애플리케이션의 보안을 강화할 수 있다.