Pages

27/04/2019

[Spring Boot] Configure CORS

CORS (Cross-origin resource sharing) is an important security aspect of modern web applications. To prevent malicious content from being pulled into your page, usually the source(s) of the content for it are restricted to prevent external domains from serving pieces of your final page.
This functionality goes along with CSRFX-Frame-Options, SessionPolicy and SecurityHeaders to provide a complete setup for your application.

All of this can be however very easily configured in Spring version 4+ (and therefore Spring Boot 2 as well) by providing a custom SecurityConfig (WebSecurityConfigurerAdapter) that will prevent Spring Boot from autoconfiguring the security with its own defaults.

Here is a sample implementation for Spring Boot 2 that completely disables (allows everything) CORS, it comes from this StackOverflow, slightly modified:



 package com.blogspot.groglogs.springboot.security;  
   
 import java.util.ArrayList;  
 import java.util.List;  
   
 import org.springframework.context.annotation.Bean;  
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;  
 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;  
 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;  
 import org.springframework.security.config.http.SessionCreationPolicy;  
 import org.springframework.web.cors.CorsConfiguration;  
 import org.springframework.web.cors.CorsConfigurationSource;  
 import org.springframework.web.cors.UrlBasedCorsConfigurationSource;  
   
 @EnableWebSecurity  
 public class SecurityConfig extends WebSecurityConfigurerAdapter {  
   
   @Override  
   public void configure(HttpSecurity http) throws Exception {  
     http.csrf().disable(); //If you do not want CSRF protection. Sometimes you might need to disable this depending on how you configure CORS  
   
     http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); //If you do not want sessions at all  
   
     http.headers().frameOptions().sameOrigin(); //If you want to allow SAMEORIGIN frame options  
   
     http.cors(); //Adds a CORS filter which we will configure manually  
   
   }  
   
   @Bean  
   public CorsConfigurationSource corsConfigurationSource() {  
     final CorsConfiguration configuration = new CorsConfiguration();  
   
     //All these lists can be cerated in one shot as Guava ImmutableList for example  
   
     List<String> allowedOrigins = new ArrayList<>();  
     allowedOrigins.add("*"); //@TODO BAD! Will allow EVERY origin, meaning CORS is disabled. Configure accordingly  
     configuration.setAllowedOrigins(allowedOrigins);  
   
     List<String> allowedMethods = new ArrayList<>();  
     //@TODO again, configure accordingly  
     allowedMethods.add("HEAD");  
     allowedMethods.add("GET");  
     allowedMethods.add("POST");  
     allowedMethods.add("PUT");  
     allowedMethods.add("DELETE");  
     allowedMethods.add("PATCH");  
     configuration.setAllowedMethods(allowedMethods);  
   
     //Prevents "The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'." Error  
     configuration.setAllowCredentials(true);  
   
     /*  
     Prevents errors on preflight (OPTIONS) requests due to CORS filter configuration  
     If the CORS filter is NOT the first one, Spring will try to perform authorization and reject the request with 403  
     */  
     List<String> allowedHeaders = new ArrayList<>();  
     allowedHeaders.add("Authorization");  
     allowedHeaders.add("Cache-Control");  
     allowedHeaders.add("Content-Type");  
     configuration.setAllowedHeaders(allowedHeaders);  
   
     //Apply our configuration everywhere  
     final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();  
     source.registerCorsConfiguration("/**", configuration);  
   
     return source;  
   }  
 }  
   

No comments:

Post a Comment

With great power comes great responsibility