@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web.ignoring().antMatchers("/css/**", "/js/**", "/images/**",
"/lib/**", "/productimgs/**");
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf().disable() // 기본적으로 RESTAPI를 사용할 경우 필요가 없어짐
.exceptionHandling()
/* 기본 시큐리티 설정에서 JWT 토큰과 관련된 유효성과 권한 체크용 설정 */
.authenticationEntryPoint(jwtAuthenticationEntryPoint)
// 유효한 자격 증명 없을 시(401)
.accessDeniedHandler(jwtAccessDeniedHandler)
// 필요한 권한 없이 접근 시(403)
.and()
.authorizeRequests()
.antMatchers("/").authenticated()
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
// cors를 위해 preflight 요청 처리용 options 요청 허용
.antMatchers("/auth/**").permitAll() // 하단 주석 참조
.antMatchers("/api/v1/products/**").permitAll()
.antMatchers("/api/v1/reviews/**").permitAll()
// .antMatchers("/api/**").hasRole("USER")
// .antMatchers("/api/**").hasRole("ADMIN")
.antMatchers("/api/**").hasAnyRole("USER", "ADMIN")
// 어떤 요청이든 허용 가능, 시큐리티를 활용한 로그인이 모두 완성 되지 않았을 때 활용할 것
.and()
/* 세션 인증 방식을 쓰지 않겠다는 설정 */
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.cors()
.and()
/* jwt 토큰 방식을 쓰겠다는 설정 */
.apply(new JwtSecurityConfig(tokenProvider));
return http.build();
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("<http://localhost:3000>"));
configuration.setAllowedMethods(Arrays.asList("GET", "PUT", "POST", "DELETE"));
configuration.setAllowedHeaders(Arrays.asList("Access-Control-Allow-Origin"
, "Content-type"
, "Access-Control-Allow-Headers", "Authorization"
, "X-Requested-With"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
CORS(Cross Origin Resource Sharing)란?
기본적으로 웹에서 저 “출처”가 동일하면 문제가 없음