스프링 시큐리티 SecurityConfig 설정(스프링부트 2.x.x vs 3.x.x)
by 볼빵빵오춘기
스프링부트 2.x.x 으로 공부하다가 버전 2.x.x가 끝나고 3.x.x으로 변경해서 프로젝트를 만들었어야했다.
아 뭐 문제 있겠어. 하면서 그냥 아무생각없이 버전3.x.x으로 시작했는데 뭐 java 버전도 11에서 17로 변경 이 부분까지는 별 문제 없이 지나갔던것같다.
하지만 혼자 공부하면서 SecurityConfig는 공부한 내용 확인 없이는 혼자 설정하기가 어려웠기에 보면서 할려고 했으나 응..? 뭐야 왜 안돼? 이런 부분이 많았었던 것 같다.
변경된지 얼마안되서 검색하는데도 정확한 참고할만한걸 찾기 어려웠던 것 같다.
개발자 커뮤니티 사이트에도 이 부분 설정때문에 글도 올라온것을 보고 설정 방법이 바꼈다는것을 알았다.
어후.. 하필.. 지금.. 이란 생각이 들었지만 어찌 검색해서 변경했던 것 같다.
이 블로그 글을 작성하는 지금은 시작할 때에 비해 어떻게 변경됐는지 어떻게 변경해야하는지 글이 많이 올라와 있었다.
나 같은 병아리에겐 조금의 변화도 크게 온다.
하지만 어쩌겠어 변화에 적응해야지 ㅋㅋ
스프핑 시큐리티 SecurityConfig 설정
스프링 부트 2.x.x
@Configuration @EnableWebSecurity // 스프링 시큐리티 필터가 스프링 필터체인에 등록이 된다. @EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true) // secured 어노테이션 활성화, preAuthorize 어노테이션 활성화 public class SecurityConfig extends WebSecurityConfigurerAdapter{ @Autowired private PrincipalOauth2UserService principalOauth2UserService; // 해당 메서드의 리턴되는 오브젝트를 IoC로 등록해준다. @Bean public BCryptPasswordEncoder encodePwd() { return new BCryptPasswordEncoder(); } @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable(); http.authorizeRequests() .antMatchers("/user/**").authenticated() .antMatchers("/manager/**").access("hasRole('ROLE_ADMIN') or hasRole('ROLE_MANAGER')") .antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')") .anyRequest().permitAll() .and() .formLogin() .loginPage("/loginForm") .loginProcessingUrl("/login") // login 주소가 호출이 되면 시큐리티가 낚아채서 대신 로그을 진행 .defaultSuccessUrl("/") .and() .oauth2Login() .loginPage("/loginForm") // 구글 로그인이 완료된 뒤의 후처리가 필요함. Tip. 코드x, 액세스토큰+사용자정보를 한 방에 .userInfoEndpoint() .userService(principalOauth2UserService); } }
스프링 부트 3.x.x
@Configuration // @EnableWebSecurity // 스프링 시큐리티 필터가 스프링 필터체인에 등록 @EnableMethodSecurity(securedEnabled = true, prePostEnabled = true) // controller에 권한설정 public class SecurityConfig{ @Autowired private PrincipalOauth2UserService principalOauth2UserService; private final PrincipalDetailsService userDetailsService; public SecurityConfig(PrincipalDetailsService userDetailsService) { this.userDetailsService = userDetailsService; } @Bean public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception { return authenticationConfiguration.getAuthenticationManager(); } @Bean public BCryptPasswordEncoder encodePwd() { return new BCryptPasswordEncoder(); } @Bean public LoginSuccessHandler loginSuccessHandler(){ return new LoginSuccessHandler(); } @Bean public LoginFailureHandler loginFailureHandler(){ return new LoginFailureHandler(); } @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{ http.formLogin((formLogin) -> formLogin.loginPage("/loginForm").loginProcessingUrl("/login").successHandler(loginSuccessHandler()).failureHandler(loginFailureHandler())) .authorizeHttpRequests(authorize -> authorize .requestMatchers("/login").permitAll() // 추가부분 .requestMatchers("/user/**").hasAnyRole("USER","SHELTER","ADMIN") // /user/** url => user, center, admin 권한이 있는 사용자만 접근 가능 .requestMatchers("/center/**").hasAnyRole("CENTER","ADMIN") // /center/** url => center, admin 권한이 있는 사용자만 접근 가능 .requestMatchers("/admin/**").hasAnyRole("ADMIN") // /center/** url => admin 권한이 있는 사용자만 접근 가능 .anyRequest().permitAll() // 권한을 주지않은 url 이 아니면 접근 허용 ).oauth2Login((oauth2) -> oauth2 .loginPage("/loginForm").userInfoEndpoint(userInfoEndpoint -> userInfoEndpoint .userService(principalOauth2UserService)).successHandler(loginSuccessHandler()).failureHandler(loginFailureHandler())) ; http.csrf(CsrfConfigurer::disable).cors(Customizer.withDefaults()); return http.build(); } }
스프링 시큐리티 설정 어떤 점이 바뀌었나?
스프링 부트 2.x.x에서 3.x.x로 업그레이드하면서, 스프링 시큐리티에도 여러 가지 중요한 변화가 있다.
WebSecurityConfigurerAdapter Deprecated
- 2.x.x: WebSecurityConfigurerAdapter를 확장하여 보안 구성을 작성했다.
- 3.x.x: WebSecurityConfigurerAdapter가 더 이상 사용되지 않으며, 대신 SecurityFilterChain을 사용하는 방식으로 변경됐다.
2.x.x
public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { // .. 생략 } }
3.x.x
@Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { // .. 생략 } }
HttpSecurity API 변경
- API가 조금 더 명확하고 유연하게 변경됐다.
- authorizeRequests()는 authorizeHttpRequests()로 변경됐다.
※ 위의 전체 코드 확인해보기 ( 2.x.x - configure(HttpSecurity http) 구현부 부분, 3.x.x - securityFilterChain(HttpSecurity http 구현부 부분)
Lambda 사용 권장
- 보안 설정을 정의할 때 람다 표현식을 사용하는 방식이 권장되고 있다.
- 코드의 가독성을 높여주고 설정을 더 직관적으로 만들어줬다.
※ 위의 전체 코드 확인해보기 ( 2.x.x - configure(HttpSecurity http) 구현부 부분, 3.x.x - securityFilterChain(HttpSecurity http 구현부 부분)
CSRF 설정 변경
CSRF 설정에서 csrf().disable()과 같은 메소드 체이닝 방식에서 CsrfConfigurer를 이용한 설정으로 바뀌었다.
2.x.x
http.csrf().disable();
3.x.x:
http.csrf(csrf -> csrf.disable());
느낀 점
- 스프링 부트 2.x.x에서 3.x.x로 업그레이드할 때는 보안 설정 방식에 많은 변화가 있기 때문에, 각 메소드와 설정 옵션을 주의 깊게 검토하고 마이그레이션하는 것이 중요하다!
- 람다식 뭔가 혼자할려면 어렵다. 이 참에 조금 더 람다식 연습 더 해보자!
참고링크

블로그의 정보
Hello 춘기's world
볼빵빵오춘기