환경
- SpringBoot 2.7
- Java17
- Spring Security
//spring security
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.security.oauth.boot:spring-security-oauth2-autoconfigure:2.6.3'
문제 발생
SpringBoot 2.7+ 버전에서 Spring Security의 WebSecurityConfigurerAdapter를 통해 security config를 override 할 때 오류가 발생하였다.
원인
공식 홈페이지를 보면, spring security 5.7이상에서 더 이상 WebSecurityConfigurerAdapter 사용을 권장하지 않는다고 한다.
해결방안
SecurityFilterChain Bean 등록을 통해 해결한다.
- 기존 코드
package com.mbti.user.config.security;
import com.mbti.user.user.dto.Role;
import com.mbti.user.user.service.CustomOAuth2UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.web.SecurityFilterChain;
@Configuration
@RequiredArgsConstructor
@EnableWebSecurity // Spring Security 설정 활성화
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final CustomOAuth2UserService customOAuth2UserService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.headers().frameOptions().disable()
.and()
.authorizeRequests()
.antMatchers("/", "/css/**", "/images/**",
"/js/**", "/h2-console/**").permitAll()
.antMatchers("/api/v1/**").hasRole(Role.
USER.name())
.anyRequest().authenticated()
.and()
.logout()
.logoutSuccessUrl("/")
.and()
.oauth2Login()
.userInfoEndpoint()
.userService(customOAuth2UserService);
}
}
- 변경 코드
package com.mbti.user.config.security;
import com.mbti.user.user.dto.Role;
import com.mbti.user.user.service.CustomOAuth2UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.security.ConditionalOnDefaultWebSecurity;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
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.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.web.SecurityFilterChain;
import static org.springframework.security.config.Customizer.withDefaults;
@EnableWebSecurity
@RequiredArgsConstructor
@Configuration(proxyBeanMethods = false)
@ConditionalOnDefaultWebSecurity
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
public class SecurityConfig {
private final CustomOAuth2UserService customOAuth2UserService;
@Bean
@Order(SecurityProperties.BASIC_AUTH_ORDER)
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.headers().frameOptions().disable()
.and()
.authorizeRequests()
.antMatchers("/", "/css/**", "/images/**",
"/js/**", "/h2-console/**").permitAll()
.antMatchers("/api/v1/**").hasRole(Role.
USER.name())
.anyRequest().authenticated()
.and()
.logout()
.logoutSuccessUrl("/")
.and()
.oauth2Login()
.userInfoEndpoint()
.userService(customOAuth2UserService);
return http.build();
}
}
오류
- 공식 문서를 따라서 @Bean 객체를 등록하면 아래 오류를 만날 수 있다.
found websecurityconfigureradapter as well as securityfilterchain. please select just one.
해결방법
https://minkukjo.github.io/framework/2021/01/16/Spring-Security-04/
- SpringBoot에서 이미 default로 SecurityFilterChain을 등록하는 데, @Bean객체로 다시 주입하게 되면서 둘 중 하나만 선택하라는 오류가 나타나는 것이다.
@ConditionalOnDefaultWebSecurity
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
위 두 annotation을 class 위에 추가하고,
@Order(SecurityProperties.BASIC_AUTH_ORDER)
위 annotation을 filter 함수 위에 추가하면 정상 작동이 된다.
'PROJECT' 카테고리의 다른 글
[SpringBoot] Spring Boot 3.0.0 버전 설정 (0) | 2022.02.20 |
---|---|
[Vue.js] 백엔드/프론트엔드 연결하기 with axios (0) | 2022.02.02 |
[SpringBoot] Swagger v2.6.2 추가하기 with gradle (0) | 2022.01.31 |
[SpringBoot] 열리는 Port 변경하기 (0) | 2022.01.24 |
[SpringBoot] Spring Initializr로 스프링부트 실행하기 (0) | 2022.01.23 |