ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Spring Security CORS
    FrameWork/Spring Security 2020. 6. 2. 16:15

    CORS란?

    - HTTP 요청은 기본적으로 Cross-Site HTTP Requests가 가능합니다. Simple 하게 다른 도메인의 Resource를 사용하는것을 말합니다. 하지만 Cross-Site HTTP Requests는 Same Origin Policy를 적용 받기 때문에 요청이 불가합니다. 즉 프로토콜, 호스트명, 포트가 같아야만 요청이 가능하다.

     

    출처 : https://t1.daumcdn.net/cfile/tistory/256C904258CB85E01E

    SPA(Single Page Application) 개발이 보편적으로 이루어 지고있어서 Front , Back사이에 도메인이 달라지는 경우가 많다 이경우에는 CORS 허용 정책이 필요하다.

    CORS 요청의 종류

    - CORS요청의 경우 Simple/Preflight, Credential/Non-Credential 4가지의 요청이존재합니다. 브라우저가 요청 내용을 분석하여 4가지 방식중 해당하는 방식으로 서버에 요청을 보내기때문에 , 프로그래머가 목적에 맞는 방식을 선택하고 그 조건에 맞게 구현해야 합니다.

    1. Simple Request

    - 아래의 조건을 모두 만족하면 Simple Request

    * GET, POST, HEAD 중의 한가지 Method를 사용

    * POST 방식일 경우에는 Content-type이 셋중에 하나여야한다.

               1. application/x-www-form-urlencoded

               2. multipart/form-data

               3. text/plain

    * Custom Header를 전송하면 안된다.

    Simple Request경우 서버에 1회 Request, 서버도 1회 Response 하는것으로 처리가 종료된다.

    2. Preflight Request

    - Simple Request 조건에 해당하지않을때 Request방식 이 요청방식은 예비 요청과 본 요청으로 나누어서 전송하게 됩니다. 따라서 브라우저는 예비요청을 보내고 응답받고 본요청을 보내고 응답받고 2번의 처리가 이루어지게 됩니다.

     하지만 예비요청과 본요청에대한 서버단의 응답을 프로그래머가 직접 프로그램내에서 구분해서 처리하지 않습니다. Access-Control- 계열의 Response Header만 적절하게 정해주면, OPTIONS 요청으로 오는 예비 요청 과 POST, GET, HEAD, PUT ,DELETE로 오는 본요청의 처리는 알아서 이루어지게 됩니다.

     

    CORS 허용 관련 문제 발생

    - 프론트 분과 협업 하면서 AWS상의 Back End서버에 Ajax 요청을 보내면서 CORS 허용 문제에 직면했다. 이를 해결하기위해 열심히 구글링을 해서 찾아본결과 현재 BackEnd 프로젝트에는 인증부분을 스프링 시큐리티로 처리하고 있는데. 이경우 간단하게 스프링 시큐리티 설정으로 CORS허용을 할수가 있었다.

     

     

    스프링 시큐리티 CORS 허용 정책

    @RequiredArgsConstructor
    @EnableWebSecurity
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
        private final JwtTokenProvider jwtTokenProvider;
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                    .httpBasic().disable()
                    .cors().configurationSource(corsConfigurationSource())  ---------- (1)
    //                .headers().frameOptions().disable()
                    .and()
                        .csrf().disable()
                    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                    .and()
                        .authorizeRequests()
                            .antMatchers("/api/v1/shops/**").hasRole("OWNER")
                            .antMatchers(HttpMethod.PUT, "/api/v1/users/**").hasAnyRole("USER", "OWNER")
                            .antMatchers(HttpMethod.DELETE, "/api/v1/users/**").hasAnyRole("USER", "OWNER")
                            .antMatchers(HttpMethod.GET, "/api/v1/users/").hasAnyRole("USER", "OWNER")
                            .anyRequest().permitAll()
                    .and()
                        .addFilterBefore(new JwtAuthenticationFilter(jwtTokenProvider),
                                UsernamePasswordAuthenticationFilter.class);
    
    
        }
        
        // CORS 허용 적용
        @Bean --------- (2)
        public CorsConfigurationSource corsConfigurationSource() {
            CorsConfiguration configuration = new CorsConfiguration();
    
            configuration.addAllowedOrigin("*");
            configuration.addAllowedHeader("*");
            configuration.addAllowedMethod("*");
            configuration.setAllowCredentials(true);
    
            UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
            source.registerCorsConfiguration("/**", configuration);
            return source;
        }
     }

    (1) - > CorsConfigurationSource 를 cors 정책의 설정파일 등록하는 부분 이거 안해주면...설정한 의미가 없습니다

    (2) -> Cors 허용 정책 설정하는 Bean 

                           * addAllowedOrigin() : 허용할 URL

                           * addAllowedHeader() : 허용할 Header

                           * addAllowedMethod() : 허용할 Http Method

     

     

    ps) 구글은 신이 분명하다...다있다 다있어 너무 좋다~~ 빠르게 해결할수 있어서

    댓글

Designed by Tistory.