개발환경
java 17.0.8
spring 3.2.0
React.js, 스프링 부트, AWS로 배우는 웹 개발 101 2/e
(제목 너무 김 ㅠ) 책을 따라하는 도중 책 예시에 있던
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigureApator;
위와 같이 WebSecurityConfigureApator
를 import 하는 부분이 Cannot resolve symbol WebSecurityConfigureApator'
해당 에러로 인해 import 되지 않는 에러를 발견하였다.
package com.example.demo.config;
import com.example.demo.security.JwtAuthenticationFilter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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.http.SessionCreationPolicy;
import org.springframework.web.filter.CorsFilter;
@EnableWebSecurity
@Slf4j
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private JwtAuthenticationFilter jwtAuthenticationFilter;
@Override
protected void configure(HttpSecurity http) throws Exception {
// http 시큐리티 빌더
http.cors() // WebMvcConfig에서 이미 설정했으므로 기본 cors 설정.
.and()
.csrf()// csrf는 현재 사용하지 않으므로 disable
.disable()
.httpBasic()// token을 사용하므로 basic 인증 disable
.disable()
.sessionManagement() // session 기반이 아님을 선언
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests() // /와 /auth/** 경로는 인증 안해도 됨.
.antMatchers("/", "/auth/**").permitAll()
.anyRequest() // /와 /auth/**이외의 모든 경로는 인증 해야됨.
.authenticated();
// filter 등록.
// 매 요청마다
// CorsFilter 실행한 후에
// jwtAuthenticationFilter 실행한다.
http.addFilterAfter(
jwtAuthenticationFilter,
CorsFilter.class
);
}
}
Spring Security without the WebSecurityConfigurerAdapter
Spring 블로그를 보면 Spring Security 5.7.0-M2에서는 WebSecurityConfigureApator
를 더이상 사용하지 않는 다고 나와있다.
HttpSecurity 구성
Spring Security 5.4에서는 SecurityFilterChain
Bean을 생성하여 HttpSecurity를 구성하는 기능을 도입하였다.
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authz) -> authz
.anyRequest().authenticated()
)
.httpBasic(withDefaults());
}
}
만약 위와 같이 WebSecurityConfigurerAdapter
를 사용하여 엔드포인트를 보호한다면
@Configuration
public class SecurityConfiguration {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authz) -> authz
.anyRequest().authenticated()
)
.httpBasic(withDefaults());
return http.build();
}
}
변경된 권장 방법은 SecurityFilterChain
Bean을 등록하는 것이다.
따라서
package com.example.demo.config;
import com.example.demo.security.JwtAuthenticationFilter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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.http.SessionCreationPolicy;
import org.springframework.web.filter.CorsFilter;
@EnableWebSecurity
@Slf4j
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private JwtAuthenticationFilter jwtAuthenticationFilter;
@Override
protected void configure(HttpSecurity http) throws Exception {
// http 시큐리티 빌더
http.cors() // WebMvcConfig에서 이미 설정했으므로 기본 cors 설정.
.and()
.csrf()// csrf는 현재 사용하지 않으므로 disable
.disable()
.httpBasic()// token을 사용하므로 basic 인증 disable
.disable()
.sessionManagement() // session 기반이 아님을 선언
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests() // /와 /auth/** 경로는 인증 안해도 됨.
.antMatchers("/", "/auth/**").permitAll()
.anyRequest() // /와 /auth/**이외의 모든 경로는 인증 해야됨.
.authenticated();
// filter 등록.
// 매 요청마다
// CorsFilter 실행한 후에
// jwtAuthenticationFilter 실행한다.
http.addFilterAfter(
jwtAuthenticationFilter,
CorsFilter.class
);
}
}
package com.example.demo.config;
import com.example.demo.security.JwtAuthenticationFilter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.web.filter.CorsFilter;
@EnableWebSecurity
@Slf4j
public class WebSecurityConfig {
@Autowired
private JwtAuthenticationFilter jwtAuthenticationFilter;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
// http 시큐리티 빌더
http.cors() // WebMvcConfig에서 이미 설정했으므로 기본 cors 설정.
.and()
.csrf()// csrf는 현재 사용하지 않으므로 disable
.disable()
.httpBasic()// token을 사용하므로 basic 인증 disable
.disable()
.sessionManagement() // session 기반이 아님을 선언
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests() // /와 /auth/** 경로는 인증 안해도 됨.
.anyMatchers("/", "/auth/**").permitAll()
.anyRequest() // /와 /auth/**이외의 모든 경로는 인증 해야됨.
.authenticated();
// filter 등록.
// 매 요청마다
// CorsFilter 실행한 후에
// jwtAuthenticationFilter 실행한다.
http.addFilterAfter(
jwtAuthenticationFilter,
CorsFilter.class
);
return http.build();
}
}
SecurityFilterChain
Bean을 등록한다.
http부분에서 deprecated 오류가 날텐데 deprecated 된 부분들을 spring 문서들에 따라 변경해준다.
package com.example.demo.config;
import com.example.demo.security.JwtAuthenticationFilter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.Customizer;
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.configurers.CsrfConfigurer;
import org.springframework.security.config.annotation.web.configurers.HttpBasicConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.web.filter.CorsFilter;
@EnableWebSecurity
@Slf4j
public class WebSecurityConfig {
@Autowired
private JwtAuthenticationFilter jwtAuthenticationFilter;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
// http 시큐리티 빌더
http
.cors(Customizer.withDefaults()) // WebMvcConfig에서 이미 설정했으므로 기본 cors 설정.
.csrf(CsrfConfigurer::disable)// csrf는 현재 사용하지 않으므로 disable
.httpBasic(HttpBasicConfigurer::disable)// token을 사용하므로 basic 인증 disableß
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) // session 기반이 아님을 선언
.authorizeHttpRequests(authorize ->
authorize
.requestMatchers("/", "/auth/**").permitAll()
.anyRequest().authenticated()
);
// /와 /auth/** 경로는 인증 안해도 됨.
// /와 /auth/**이외의 모든 경로는 인증 해야됨.
// filter 등록.
// 매 요청마다
// CorsFilter 실행한 후에
// jwtAuthenticationFilter 실행한다.
http.addFilterAfter(
jwtAuthenticationFilter,
CorsFilter.class
);
return http.build();
}
}
Configuration Migrations :: Spring Security
Authentication Persistence and Session Management :: Spring Security
+) 위 코드를 실행하고 signup을 실행하면 401 에러를 뱉기에 @Configuration 어노테이션을 추가하니 해결되었다
- 참고 링크
https://docs.spring.io/spring-security/reference/5.8/migration/servlet/config.html
package com.example.demo.config;
import com.example.demo.security.JwtAuthenticationFilter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.CsrfConfigurer;
import org.springframework.security.config.annotation.web.configurers.HttpBasicConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.web.filter.CorsFilter;
@Configuration
@EnableWebSecurity
@Slf4j
public class WebSecurityConfig {
@Autowired
private JwtAuthenticationFilter jwtAuthenticationFilter;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
// http 시큐리티 빌더
http
.cors(Customizer.withDefaults()) // WebMvcConfig에서 이미 설정했으므로 기본 cors 설정.
.csrf(CsrfConfigurer::disable)// csrf는 현재 사용하지 않으므로 disable
.httpBasic(HttpBasicConfigurer::disable)// token을 사용하므로 basic 인증 disableß
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) // session 기반이 아님을 선언
.authorizeHttpRequests(authorize ->
authorize
.requestMatchers("/", "/auth/**").permitAll()
.anyRequest().authenticated()
);
// /와 /auth/** 경로는 인증 안해도 됨.
// /와 /auth/**이외의 모든 경로는 인증 해야됨.
// filter 등록.
// 매 요청마다
// CorsFilter 실행한 후에
// jwtAuthenticationFilter 실행한다.
http.addFilterAfter(
jwtAuthenticationFilter,
CorsFilter.class
);
return http.build();
}
}
최종 코드..