WebSecurityConfiguration:
。Spring Security의웹 보안에설정을 담당하는@Configuration Class
。Authentication,Authorization,CSRF Protection등의 보안정책을 설정한SecurityFilterChain 객체를@Bean method를 통해Spring Bean으로 등록
SpringBootWebSecurityConfiguration
。Servlet 어플리케이션을 보호하는 역할의WebSecurityConfiguration Class
▶ 웹보안을 위한 Default로 설정된Configuration Class.
。Spring은 기본적으로FilterChain을 통해 명시적으로 인증된HTTP Request에 대해서만 허용 및formLogin()과httpBasic()이 기본적으로 활성화 설정되도록 설정됨.
▶CsrfFilter도 기본적으로 활성화 설정이 되어있음.
WebSecurityConfigurationClass 설정@Configuration public class SecurityConfig { @Value("${custom.baseUrl}") public String BASE_URL; // @Bean SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { return http .csrf(AbstractHttpConfigurer::disable) .cors(Customizer.withDefaults()) .httpBasic(basic -> basic.disable()) .formLogin(formLogin -> formLogin.disable()) // H2 설정 시 <iframe> 필요 .headers(headers -> headers.frameOptions(frame -> frame.sameOrigin())) .sessionManagement(session->session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .oauth2Login(Customizer.withDefaults()) .authorizeHttpRequests(auth -> auth // 개발 환경에서 필요한거 추후 운영에서 빼야됨 .requestMatchers("/h2-console/**", "/api/actuator/**", "/swagger-ui/**", "/v3/api-docs/**" ).permitAll() // // Preflight Request 허용 .requestMatchers(CorsUtils::isPreFlightRequest).permitAll() // // 로그인 / 회원가입은 익명 사용자만 가능 .requestMatchers(HttpMethod.GET, EndPoints.GET_ANONYMOUS).anonymous() .requestMatchers(HttpMethod.POST, EndPoints.POST_ANONYMOUS).anonymous() // .requestMatchers(HttpMethod.GET, EndPoints.GET_ADMIN_AUTHENTICATED).hasAnyRole(Role.SUPER_ADMIN.name(), Role.ADMIN.name()) .requestMatchers(HttpMethod.GET, EndPoints.GET_AUTHENTICATED).authenticated() // .requestMatchers(HttpMethod.POST, EndPoints.POST_ADMIN_AUTHENTICATED).hasAnyRole(Role.SUPER_ADMIN.name(), Role.ADMIN.name()) .requestMatchers(HttpMethod.POST, EndPoints.POST_AUTHENTICATED).authenticated() // .requestMatchers(HttpMethod.PUT, EndPoints.PUT_ADMIN_AUTHENTICATED).hasAnyRole(Role.SUPER_ADMIN.name(), Role.ADMIN.name()) .requestMatchers(HttpMethod.PUT, EndPoints.PUT_AUTHENTICATED).authenticated() // .requestMatchers(HttpMethod.PATCH, EndPoints.PATCH_ADMIN_AUTHENTICATED).hasAnyRole(Role.SUPER_ADMIN.name(), Role.ADMIN.name()) .requestMatchers(HttpMethod.PATCH, EndPoints.PATCH_AUTHENTICATED).authenticated() // .requestMatchers(HttpMethod.DELETE, EndPoints.DELETE_ADMIN_AUTHENTICATED).hasAnyRole(Role.SUPER_ADMIN.name(), Role.ADMIN.name()) .requestMatchers(HttpMethod.DELETE, EndPoints.DELETE_AUTHENTICATED).authenticated() // .anyRequest().denyAll() ) .build(); } // // CORS 관련 설정 @Bean public WebMvcConfigurer corsConfigurer(){ return new WebMvcConfigurer() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/api/**") .allowedOrigins(BASE_URL) .allowedMethods("*") .allowedHeaders("*") .allowCredentials(true) .exposedHeaders("Authorization") .maxAge(3600); } }; } // static public class EndPoints { // public static final String[] GET_ANONYMOUS = { "/api/users/login", "/api/oauth2/authorization/google", "/api/oauth2/authorization/naver"} ; public static final String[] POST_ANONYMOUS = { "/api/users/signup"} ; // public static final String[] GET_AUTHENTICATED = { "/api/users/**", "/api/posts/**", "/api/requests/**", "/api/categories/**", "/api/files/**", "/api/messages/**" } ; public static final String[] GET_ADMIN_AUTHENTICATED = { "/api/admin/**"}; // public static final String[] POST_AUTHENTICATED = { "/api/users/**", "/api/posts/**", "/api/requests/**", "/api/files/**", "/api/messages/**", "/api/feedback/**" }; public static final String[] POST_ADMIN_AUTHENTICATED = { "/api/categories/**", "/api/admin/**"}; // public static final String[] PUT_AUTHENTICATED = { "/api/users/**", "/api/posts/**", "/api/requests/**", "/api/files/**", "/api/messages/**", "/api/feedback/**" }; public static final String[] PUT_ADMIN_AUTHENTICATED = { "/api/admin/**"} ; // public static final String[] PATCH_AUTHENTICATED = { "/api/users/**", "/api/posts/**", "/api/requests/**", "/api/categories/**", "/api/files/**", "/api/messages/**", "/api/feedback/**" }; public static final String[] PATCH_ADMIN_AUTHENTICATED = { "/api/categories/**", "/api/admin/**"} ; // public static final String[] DELETE_AUTHENTICATED = { "/api/users/**", "/api/posts/**", "/api/requests/**", "/api/files/**", "/api/messages/**", "/api/feedback/**" }; public static final String[] DELETE_ADMIN_AUTHENTICATED = { "/api/admin/**"} ; } }。
WebSecurityConfiguration을 담당하는@Configuration Class내BCryptPasswordEncoder객체를 생성하여PasswordEncoder type으로Spring Bean으로 등록하는@Bean Method를 정의.
▶ 추후계정저장 시 해당Password Encoder를 통해단방향 암호화되어 저장되어복호화불가능.
。AuthentificationManager를Spring Bean으로 등록하는@Bean method정의
.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class)
。사용자가JWT 토큰을서버에 전달 시JWT 검증용도로 구축한커스텀 Filter 구현체를Spring Security Filter Chain에 포함 JWT 검증 필터
▶UsernamePasswordAuthenticationFilter가 동작하기전에 동작하도록 설정
@EnableWebSecurity
。Spring Secuirty을 활성화 및웹보안 설정을 구성하는 용도로 사용되는어노테이션
▶Spring Security를 설정 및 구성하는@Configuration Class에 선언
。WebSecurityConfiguration역할의@Configuration Class내Spring Bean으로 등록된SecurityFilterChain을 활성화
。spring-boot-starter-security 의존성추가 시 별도의어노테이션선언 없어도 자동 활성화
@EnableWebFluxSecurity
。Tomcat이 아닌Netty기반의비동기서버환경에서 선언하는어노테이션