ํ๋ก์ ํธ๋ฅผ ์งํํ๋ฉด์, SpringBoot๋ฅผ 3.1.2 ๋ฒ์ ์ ์ฌ์ฉํ๊ฒ ๋์๋ค. ์์ ์ 2.6 ~ 2.7.x ๋ฒ์ ์ ์ฌ์ฉํ ๋ JWT์ Security๋ฅผ ์ด์ฉํ์ฌ ์ ์ ์๋น์ค๋ฅผ ๋ง๋๋ ํฌ์คํ ์ด ์์๋๋ฐ ์ต์ ๋ฒ์ ์ SpringBoot์ Security๋ฅผ ์ฌ์ฉํ๋ค๋ฉด ํด๋น ํฌ์คํ ๋๋ก ๊ตฌํํ ์ ์์ ๊ฒ ์ด๋ค.
๊ทธ๋์ ์ด๋ฒ์๋ SpringBoot 3.1.2 ๋ฒ์ ๊ณผ SpringSecurity์ 6.1 ๋ฒ์ ์ ์ด์ฉํด JWT์ Security๋ฅผ ํ๊บผ๋ฒ์ ๋ค๋ค๋ณด๋ ํฌ์คํ ์ ๋ค๋ฃจ๋ ค ํ๋ค.
์ด๋ฒ ํํธ๋ SpringSecurity ์ด๋ค.
// dependency
implementation 'org.springframework.boot:spring-boot-starter-security'
testImplementation 'org.springframework.security:spring-security-test'
build.gradle์ ์์กด์ฑ์ ์ฃผ์ ํ๋ ๋ถ๋ถ์ ํฌ๊ฒ ๋ค๋ฅผ ๊ฒ ์๋ค.
๊ธฐ์กด Security ์ค์ ์ ์ ์ฉํ๊ธฐ์ํด SecurityConfig๋ผ๋ ํด๋์ค๋ฅผ ๋ง๋ค์ด์ฃผ์์๋๋ฐ, ์ด๋ฒ์๋ ๋ง์ฐฌ๊ฐ์ง๋ก ๋ง๋ค ๊ฒ ์ด๋ค. ๋ค๋ง, 2.x.x ์ฝ๋์ ๋น๊ตํด๊ฐ๋ฉด์ ์ดํด๋ณด๋๋ก ํ์.
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@RequiredArgsConstructor
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final CorsFilter corsFilter;
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.csrf().disable()
.addFilterBefore(corsFilter, UsernamePasswordAuthenticationFilter.class)
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/test","/auth","/auth/login","/docs","/test","/health","/auth/check").permitAll()
.antMatchers("/docs/**").permitAll()
.antMatchers("/docs/index.html").permitAll()
.anyRequest().authenticated();
}
}
Jwt๋ฅผ ์ ์ฉํ๊ธฐ ์ ์ 2.6.x ๋ฒ์ ์ SecurityConfig ํด๋์ค์ด๋ค. WebSecurityConfigurerAdapter๋ผ๋ ์ธํฐํ์ด์ค๋ฅผ ์์๋ฐ์ ์ค๋ฒ๋ผ์ด๋ฉํ ํจ์ ๋ด๋ถ์์ Security์ ๊ด๋ จ๋ ์ค์ ์ ํด์ฃผ์์๋๋ฐ, ๋ฐฉ๋ฒ์ด ๋ฌ๋ผ์ก๋ค.
๋ํ and() ์ ๊ฐ์ non-lamda DSL methods ๋ค์ด ์ ๋ถ deprecated ๋์๋ค. ์ด์ ๋ lamda-DSL๋ก ์ค์ ์ ๊ตฌ์ฑํ๊ฒ ๋์๋ค.
์ ์ด๋ ๊ฒ ๋๋์ง ๊ถ๊ธํ๋ฉด ์๋์ ๋ฌธ์๋ฅผ ์ดํด๋ณด๋๋ก ํ์ ๐คจ
https://docs.spring.io/spring-security/reference/migration-7/configuration.html
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
@RequiredArgsConstructor
public class SecurityConfig {
private final CorsFilter corsFilter;
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf(AbstractHttpConfigurer::disable)
.addFilterBefore(corsFilter, UsernamePasswordAuthenticationFilter.class)
.sessionManagement(session -> session
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
)
.authorizeHttpRequests(request -> request
.requestMatchers(
"/version", "/login/google"
)
.permitAll()
)
.authorizeHttpRequests(request -> request.anyRequest().authenticated())
return http.build();
}
}
๋ฑ๋ด๋ ๋ญ๊ฐ ๋ง์ด ๋ฐ๋ ๊ฒ ๊ฐ๊ธดํ๋ค... ๊ทธ๋์ ์ค๋ช ์ ๊ณ๋ค์ด์๋ฉด
์ด๊ฒ ๊ทธ๋๋ ์ฝ๋ ์ ์ฒด๊ฐ ๋ง์ด ๋ฐ๋ ๊ฒ ๊ฐ์๋, ๊ตฌํํ๋ ๋ฐฉ์์ด ํ๋ ค์ง๊ฑด ์๋๊ธฐ์ ๊ธฐ์กด์ ์ฝ๋๋ฅผ ์ฝ๊ฒ ์์ ํ ์ ์๋ค.
Security 2.6.x ~ ๋ถํฐ ์ฌ์ฉํ๋ค๋ณด๋ ์ต์ํด์ ธ์ ์ฝ๊ฒ ๋ฐ๊ฟ ์ ์์๊น ํ๋๋ฐ, ๊ทธ๋๋ ๊ณต์๋ฌธ์๋ ์ฌ๋ฌ ์๋ฃ๋ค์ด ๋ง์ ๋ฒ์ ์ด ๋์์ ธ๋ ์ฝ๊ฒ ๋ฐ๊ฟ ์ ์์๋ค. andDo()๋ฅผ ์ฌ์ฉํ๋ non-lamda ๋ฐฉ์์ด ์ฌ์ค ํ์์ ๊ฒฝ์ฐ ๊ทธ๋ฅ ์ข์ง ์์๋๋ฐ, lamda ํ์์ ์ฌ์ฉํ๊ฒ ๋ฐ๋๊ฒ ๋๋ฉด์ ๋ญ๊ฐ ๋ ์ข์์ง ๊ฒ ๊ฐ๋ค(?)
์๋ฌดํผ ์ด๋ฒ ํฌ์คํ ๋ ์ฌ๊ธฐ์ ๋! ๋ค์์๋ JWT ๊น์ง ๊ฐ์ด ์ฌ์ฉํด๋ณด์