[헤이동동 #07] WebSecurityConfigurerAdapter 구현

Jiwoo Kim·2020년 12월 2일
0
post-thumbnail

☕헤이동동 : 생협 음료 원격 주문 서비스

이번 포스팅에서는 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 검증 필터가 작동해야 하기 때문이다.


전체 코드는 Github에서 확인하실 수 있습니다.

0개의 댓글