package com.showmycnft.root.config.auth;
import com.showmycnft.root.domain.user.Role;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
@RequiredArgsConstructor
@EnableWebSecurity //Spring Security 설정을 활성화하는 어노테이션
public class SecurityConfig {
private final CustomOAuth2UserService customOAuth2UserService;
@Bean
protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf().disable()
.headers().frameOptions().disable() //h2 console 화면을 사용하기 위해 해당 옵션들을 사용하지 않을 것 입니다.
.and().authorizeRequests() //URL별 권한 관리를 설정하는 옵션, antMatchers옵션 사용하기 위함
.antMatchers("/", "/css/**", "/images/**", "/js/**", "/h2-console/**").permitAll() //권한 관리 대상을 지정
.antMatchers("/api/v1/**").hasRole(Role.USER.name()) //RBAC
.anyRequest().authenticated() //나머지 처리 authenticated()를 추가해서 나머지는 모두 인증된 사용자들에게만 허용하게함
.and().logout().logoutSuccessUrl("/") //로그아웃 기능에 대한 여러 설정의 진입점이고 로그아웃 시 /로 이동
.and().oauth2Login() //
.userInfoEndpoint() //OAuth 2 로그인 성공 이후 사용자 정보를 가져올 때의 설정들을 담당
.userService(customOAuth2UserService); // 소셜 로그인 성공 시 후속 조치를 진행할 UserService 인터페이스의 구현체를 등록
return http.build();
}
}
위 코드를 작성하는 도중 antMatchers
에서 에러가 발생하였습니다. 찾아보니
HttpSecurity 객체에서 authorizeRequests() 메소드를 호출한 다음, 반환된 ExpressionInterceptUrlRegistry 객체에서 authorizeRequests() 메소드를 찾을 수 없을 때 발생한다고 합니다.
ExpressionInterceptUrlRegistry 클래스에서 이 antMatchers() 메소드를 제공하는데, 이 클래스는 spring-security-config 라이브러리에 포함되어 있어서 라이브러리 등록이 안되어 있으면 antMatchers() 메소드를 사용할 수 없다는 에러가 발생하게됩니다.
build.gradle.kts
파일에 아래의 의존성을 추가해주면 해결됩니다.
implementation ("org.springframework.security:spring-security-config:5.6.0")
만약 spring-security 5.8 이상의 버전을 사용하는 경우에는 antMatchers
, mvcMatchers
, regexMatchers
가 더 이상 사용되지 않기 때문에, requestMatchers
를 사용해야 합니다.
기존 코드
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authz) -> authz
.antMatchers("/api/admin/**").hasRole("ADMIN")
.antMatchers("/api/user/**").hasRole("USER")
.anyRequest().authenticated()
);
return http.build();
}
}
변경된 코드
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authz) -> authz
.requestMatchers("/api/admin/**").hasRole("ADMIN")
.requestMatchers("/api/user/**").hasRole("USER")
.anyRequest().authenticated()
);
return http.build();
}
}