이번 포스팅에서는 WebSecurityConfigurerAdapter
를 사용한 헤이동동의 Spring Security 설정에 대해 설명한다.
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private final JwtTokenProvider jwtTokenProvider;
@Bean
public PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.addAllowedOrigin("http://heydongdong.ewha.com.s3-website.ap-northeast-2.amazonaws.com");
configuration.addAllowedOrigin("http://heydongdong-admin.ewha.com.s3-website.ap-northeast-2.amazonaws.com");
configuration.addAllowedOrigin("http://localhost:8081");
configuration.addAllowedOrigin("http://localhost:8080");
configuration.addAllowedMethod("*");
configuration.addAllowedHeader("*");
configuration.setAllowCredentials(true);
configuration.setMaxAge(3600L);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.requestMatchers(CorsUtils::isPreFlightRequest).permitAll()
.and()
.cors()
.and()
.httpBasic().disable()
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers(HttpMethod.POST, "/user/sign-up").permitAll()
.antMatchers(HttpMethod.POST, "/user/sign-in").permitAll()
.antMatchers(HttpMethod.POST, "/user/find-info/**").permitAll()
.antMatchers(HttpMethod.POST, "/user/refresh-tokens").permitAll()
.antMatchers("/user/check-email-token/**").permitAll()
.and()
.authorizeRequests()
.antMatchers(HttpMethod.POST, "/order/update-progress").permitAll()
.antMatchers(HttpMethod.POST, "/admin/**").permitAll()
.antMatchers(HttpMethod.POST, "/menu/**").permitAll()
.and()
.authorizeRequests()
.antMatchers(HttpMethod.POST, "/user/change-pw").hasRole("USER")
.antMatchers(HttpMethod.POST, "/user/sign-out").hasRole("USER")
.antMatchers(HttpMethod.POST, "/user/no-show-count").hasRole("USER")
.antMatchers(HttpMethod.POST, "/history/**").hasRole("USER")
.antMatchers(HttpMethod.POST, "/my-menu/**").hasRole("USER")
.antMatchers(HttpMethod.POST, "/order/add").hasRole("USER")
.antMatchers(HttpMethod.POST, "/order/get-progress").hasRole("USER")
.anyRequest().authenticated()
.and()
.addFilterBefore(new JwtAuthenticationFilter(jwtTokenProvider),
UsernamePasswordAuthenticationFilter.class);
}
}
CorsConfigurationSource
이름대로 CORS 에러를 해결하기 위한 설정이다. 프론트인 Vue.js 프로젝트는 SPA(Single Page Application)으로, 배포 시 CORS 에러가 발생할 수 밖에 없다고 한다. 서버 측에서 CORS 설정을 위와 같이 제대로 해두면 어플리케이션이 잘 작동한다.
단, configure
메소드에 http.requestMatchers(CorsUtils::isPreFlightRequest).permitAll()
을 꼭! 추가해주어야 한다. 안 그러면 위의 origin 설정이 다 잘 되어 있어도 PreFlightRequest
관련 오류가 계속 나게 된다.
JwtAuthenticationFilter
유저 ROLE 인증을 위해 http.addFilterBefore(new JwtAuthenticationFilter(jwtTokenProvider), UsernamePasswordAuthenticationFilter.class)
라인을 추가해주어야 한다. 스프링 시큐리티 필터 이전에 커스텀하여 작성한 JWT 검증 필터가 작동해야 하기 때문이다.