feat : CORS, JWT Security 설정 추가
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
package com.banjjoknim.playground.config
|
||||
|
||||
import org.springframework.context.annotation.Bean
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.web.cors.CorsConfiguration
|
||||
import org.springframework.web.cors.UrlBasedCorsConfigurationSource
|
||||
import org.springframework.web.filter.CorsFilter
|
||||
|
||||
/**
|
||||
* ```kotlin
|
||||
* corsConfiguration.allowCredentials = true
|
||||
*
|
||||
* user credentials 을 허용한다. 즉, 서버가 응답을 할 때 json 을 자바스크립트에서 처리할 수 있게(응답을 받을 수 있게) 할건지 말건지를 설정한다.
|
||||
* 만약 false 로 설정할 경우, 자바스크립트로 어떤 요청을 했을 때 서버로부터 응답이 오지 않는다.
|
||||
* ```
|
||||
*
|
||||
* ```kotlin
|
||||
* corsConfiguration.addAllowedOrigin("*")
|
||||
*
|
||||
* 모든 IP에 응답을 허용한다는 설정.
|
||||
* ```
|
||||
*
|
||||
* ```kotlin
|
||||
* corsConfiguration.addAllowedHeader("*")
|
||||
*
|
||||
* 모든 Header에 응답을 허용한다는 설정.
|
||||
* ```
|
||||
*
|
||||
* ```kotlin
|
||||
* corsConfiguration.addAllowedMethod("*")
|
||||
*
|
||||
* 모든 HTTP METHOD 요청을 허용한다는 설정.
|
||||
* ```
|
||||
*
|
||||
* CorsFilter 대신 `@CrossOrigin` 어노테이션은 사용하더라도 Security 인증이 필요한 요청은 전부 거부된다.
|
||||
*
|
||||
* `@CrossOrigin` 어노테이션은 인증이 필요하지 않은 요청만 허용해준다. 예를 들어, 로그인을 해야만 할 수 있는 요청들은 모두 거부된다.
|
||||
*
|
||||
* 인증이 필요한 경우는 CorsFilter 를 Security Filter 에 등록해주어야 하고, 인증이 필요 없는 경우는 `@CrossOrigin` 어노테이션을 사용할 수 있다.
|
||||
*
|
||||
* @see org.springframework.web.cors.CorsConfiguration
|
||||
* @see org.springframework.web.cors.UrlBasedCorsConfigurationSource
|
||||
* @see org.springframework.web.filter.CorsFilter
|
||||
* @see org.springframework.web.bind.annotation.CrossOrigin
|
||||
*/
|
||||
@Configuration
|
||||
class CorsConfiguration {
|
||||
|
||||
/**
|
||||
* Spring 에서 관리하는 Bean 으로 등록한 CorsFilter 를 Security Filter 에 등록해주어야 한다.
|
||||
*
|
||||
* 단순히 Bean 으로만 등록해서는 동작하지 않는다.
|
||||
*
|
||||
* @see com.banjjoknim.playground.config.security.JwtSecurityConfiguration
|
||||
*/
|
||||
@Bean
|
||||
fun corsFilter(): CorsFilter {
|
||||
val corsConfigurationSource = UrlBasedCorsConfigurationSource() // URL 을 이용한 CORS 설정을 담아두는 객체.
|
||||
val corsConfiguration = CorsConfiguration() // CORS 설정 객체.
|
||||
corsConfiguration.allowCredentials = true
|
||||
corsConfiguration.addAllowedOrigin("*")
|
||||
corsConfiguration.addAllowedHeader("*")
|
||||
corsConfiguration.addAllowedMethod("*")
|
||||
corsConfigurationSource.registerCorsConfiguration("/api/**", corsConfiguration) // corsSource 에 corsConfiguration 을 등록한다.
|
||||
return CorsFilter(corsConfigurationSource)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.banjjoknim.playground.config.security
|
||||
|
||||
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.config.http.SessionCreationPolicy
|
||||
import org.springframework.web.filter.CorsFilter
|
||||
|
||||
/**
|
||||
* SessionCreationPolicy 설정을 STATELESS 로 사용하면 세션을 만드는 방식을 사용하지 않게 된다.
|
||||
*
|
||||
* 토큰 기반(JWT)을 사용한 설정에서는 기본이며, 상태가 없는 서버를 만들 때 사용한다.
|
||||
*
|
||||
* @see org.springframework.security.config.http.SessionCreationPolicy
|
||||
*/
|
||||
@EnableWebSecurity // 시큐리티 활성화 -> 시큐리티 설정을 기본 스프링 필터체인에 등록한다.
|
||||
class JwtSecurityConfiguration(
|
||||
private val corsFilter: CorsFilter // CorsConfiguration 에서 Bean 으로 등록해준 CorsFilter 를 Spring 으로부터 DI 받는다.
|
||||
) : WebSecurityConfigurerAdapter() {
|
||||
override fun configure(http: HttpSecurity) {
|
||||
http.csrf().disable()
|
||||
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) // 세션을 사용하지 않겠다는 설정. 토큰 기반에서는 기본 설정이다. 상태가 없는 서버를 만든다.
|
||||
.and()
|
||||
.addFilter(corsFilter) // filter 에 Bean 으로 등록해준 CorsFilter 를 추가한다. 따라서 모든 요청은 추가된 CorsFilter 를 거치게 된다. 이렇게 하면 내 서버는 CORS 정책에서 벗어날 수 있다(Cross-origin 요청이 와도 다 허용될 것이다).
|
||||
.formLogin().disable() // Form 태그 방식 로그인을 사용하지 않는다.
|
||||
.httpBasic().disable() // HttpBasic 방식 로그인을 사용하지 않는다.
|
||||
.authorizeRequests()
|
||||
.antMatchers("/api/v1/user/**").hasAnyRole("USER", "MANAGER", "ADMIN")
|
||||
.antMatchers("/api/v1/manager/**").hasAnyRole("MANAGER", "ADMIN")
|
||||
.antMatchers("/api/v1/admin/**").hasAnyRole("ADMIN")
|
||||
.anyRequest().permitAll()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user