
โญ (๋ชฉํ) ํ์๊ด๋ฆฌ API๋ฅผ ๊ตฌํ โก๏ธ ํ์๊ฐ์ , ๋ก๊ทธ์ธ, ๋ก๊ทธ์์
JWT๋ฅผ ์ฌ์ฉํด์ ๊ตฌํ
Spring Security ์ฌ์ฉ์ ์ํด configํ์ผ ์์ฑ ๊ฐ์๋ฅผ ๋ฃ๊ณ ์์๋ค.
๊ฐ์ฌ๋์ SpringBoot ๋ฒ์ ์ 2.5.6
๋์ SpringBoot ๋ฒ์ ์ 3.2.4... ๋น๊ทน์ ์์์ด์๋ค...๐
SpringBoot ๋ฒ์ ์ ๋ฐ๋ผ์ ์ค์ ํ์ผ์ด ์กฐ๊ธ์ฉ ๋ฌ๋๋ค
(SpringBoot 2.5.x ๋ฒ์ ๊ณผ SpringBoot 2.6.x ๋ฒ์ ์ ์ค์ ๋ ์ฐจ์ด๊ฐ ์๋ค)
๊ฐ์ฌ๋์ WebSecurityConfigurerAdapter๋ผ๋ ์ธํฐํ์ด์ค๋ฅผ ์์๋ฐ์ ์ค๋ฒ๋ผ์ด๋ฉํ ํจ์ ๋ด๋ถ์์ Security ๊ด๋ จ ์ค์ ์งํํ์๊ณ , SpringBoot 3.2.4์์๋ ์์ ์๋ ํจ์๋ค์ด์๋ค.
โฌ๏ธ Spring Security Config ์์ฑ ๊ธฐ์กด ๋ฐฉ์ (SpringBoot 2.5.x~)
extends WebSecurityConfigurerAdapter ์์๋ฐ์ @Override๋ก ์์ฑ
package zerobase.dividends.security;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
@Slf4j
@EnableWebSecurity
@EnableMethodSecurity
@RequiredArgsConstructor
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private final JwtAuthenticationFilter authenticationFilter;
@Override
public void configure(HttpSecurity http) throws Exception {
http
.httpBasic().disable()
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/**/signup", "/**/signin").permiAll()
.and()
.addFilterBefore(this.authenticationFilter, UsernamePasswordAuthenticationFilter.class);
}
@Override
public void configure(final WebSecurity web) throws Exception {
web.ignoring()
.antMatchers("/h2-consol/**");
}
// spring boot 2.x
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
SpringBoot 3 Spring Security ์ค์ ํ๊ธฐ ํญํ ๊ตฌ๊ธ๋ง
WebSecurityConfigurerAdapter โก๏ธ SecurityFilterChain ์ผ๋ก ๋ณ๊ฒฝ
์ฒซ๋ฒ์งธ ์์ : ์คํจ... ์๋ฌ ํญ๋ฐ ๐คฏ
500 Error๋ ๋ง๋๊ณ , ์ค๊ฐ์ parsig์ด ์ด์ํ๋ค๋ ์๋ฌ ๋ฉ์ธ์ง๋ ๋ง๋๊ณ
์ง์ง ์ ~ ์ฒญ ์๋ฌ ๋ด๋ฉด์ ๊ฒจ์ฐ ๋ณ๊ฒฝํ๋คใ
ใ
ใ

package zerobase.dividends.security;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
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.WebSecurityCustomizer;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
@Slf4j
@EnableWebSecurity
@EnableMethodSecurity
@RequiredArgsConstructor
public class SecurityConfiguration {
private final JwtAuthenticationFilter jwtAuthenticationFilter;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf(AbstractHttpConfigurer::disable)
.sessionManagement((sessionManagement) ->
sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
)
.authorizeHttpRequests((authorizeRequests) ->
authorizeRequests
.requestMatchers("/**/signup", "/**/signin").permitAll())
.addFilterBefore(this.jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web.ignoring().requestMatchers("/h2-console/**");
}
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
}
์ฝ๋๋ฅผ ์ด๋์ ๋ ์ดํดํ๊ณ ์กฐ๊ธ์ฉ ์์
"/**/signup"โก๏ธ"/*/signup"
๋ฉํ๋์ด์๋ ๊ฒ๋ค ๋ค ๋ฒ๊ฒจ์ฃผ๊ณ , ๋ณ์๋ช ๋ ๊ฐ๋จํ๊ฒ!
package zerobase.dividends.security;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
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.WebSecurityCustomizer;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
@Slf4j
@EnableWebSecurity
@EnableMethodSecurity
@RequiredArgsConstructor
public class SecurityConfiguration {
private final JwtAuthenticationFilter jwtAuthenticationFilter;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf(AbstractHttpConfigurer::disable)
.sessionManagement(sessionManagement ->
sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
)
.authorizeHttpRequests(auth -> auth
.requestMatchers("/*/signup", "/*/signin").permitAll())
.addFilterBefore(this.jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return web -> web.ignoring().requestMatchers("/h2-console/**");
}
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
}
์ด๊ฑฐ ํ์ค์ด ๋น ์ ธ์์๋ค... ์ด๊ฒ ์์ด์ 403 Error
403์๋ฌ๋ ์ง์ง ๊ทน์ ์ธ๊ฒ ๋ก๊ทธ๋ ์๋ฌ์ฝ๋๋ ์๋์์ 4์๊ฐ์ ์ฝ์งํ๋ค..
์์ธ ์ฐพ๋๋ค๊ณ ๋ก๊ทธ๋ก ๊ธฐ๋ก ๋ค ๋จ๊ธฐ๊ณ , ๋ฃจํธ ๋ก๊ทธ ๋ ๋ฒจ๋ debug ๋ก ๋ณ๊ฒฝ!
logging.level.root=debug
์ฝ๋ ๋ณ๊ฒฝํ๋ฉด์ ๋น ์ก๋๋ณด๋ค๐ซ
.anyRequest().authenticated ํ๋ก์ ํธ ๋๋๋ฉด ํ ์ค ํ ์ค ๋ฏ์ด์ฃผ๋ง
package zerobase.dividends.security;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
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.WebSecurityCustomizer;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
@Slf4j
@EnableWebSecurity
@EnableMethodSecurity
@RequiredArgsConstructor
public class SecurityConfiguration {
private final JwtAuthenticationFilter jwtAuthenticationFilter;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf(AbstractHttpConfigurer::disable)
.sessionManagement(sessionManagement ->
sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
)
.authorizeHttpRequests(auth -> auth
.requestMatchers("/*/signup", "/*/signin").permitAll()
.anyRequest().authenticated())
.addFilterBefore(this.jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return web -> web.ignoring().requestMatchers("/h2-console/**");
}
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
}
์ค๊ฐ์ ํฌ๊ธฐํ๊ณ ์ถ์๋๋ฐ, ์ค๊ธฐ๊ฐ ์๊ฒจ์ ๋ฐค์ ์ฝ๋๋ ์ธ์ ๋ค๐ซ
์ฒ์ ์๋ฌ๊ฐ ์์๋๊ณ ๊ฑฐ์ 12์๊ฐ๋ง์ ํด๊ฒฐํ๋ค....
์๋ฌ ํ๋๋ฅผ ํด๊ฒฐํ๋ฉด ๋ค์ ์๋ฌ๊ฐ ๋์ค๊ณ ,
200๋ณด๊ณ ๋ฐ์์น๊ณ ์ข์ํ๋ค ๋ค์ ๋ง๋ 505...403...
โฌ๏ธ ๊ณต์ ์ฌ์ดํธ
https://spring.io/blog/2022/02/21/spring-security-without-the-websecurityconfigureradapter
โฌ๏ธ ๋์๋ฐ์ ๋ธ๋ก๊ทธ
https://velog.io/@hwsa1004/SpringBoot-3.1.0-SpringSecurity-%EC%84%A4%EC%A0%95%ED%95%98%EA%B8%B0