Enterprise Java

Testing CORS in Spring Boot

CORS (Cross-Origin Resource Sharing) is a mechanism that allows resources on a web server to be requested from another domain. In Spring Boot, configuring and testing CORS can be straightforward, especially with the support of tools like MockMvc. Let us delve to discuss and understand how to configure CORS in a Spring Boot application and how to test it using MockMvc.

1. Introduction

Cross-Origin Resource Sharing (CORS) is a security feature implemented by web browsers to control how resources on a web server can be requested from a different domain than the one that served the web page. This is essential in modern web applications where front-end applications, often served from a different domain (e.g., localhost:3000), need to interact with back-end services on another domain (e.g., api.example.com). Without CORS, browsers would block such cross-origin requests to protect users from potential security threats. However, when configured correctly, CORS allows safe and controlled communication between different domains. In a Spring Boot application, CORS can be configured at various levels to specify which domains are allowed to access the server’s resources, what HTTP methods are permitted, and whether credentials such as cookies can be shared. Understanding and testing CORS configuration is crucial for ensuring that your application behaves as expected in a cross-domain environment while maintaining security.

2. Configuring CORS in Spring Boot

Spring Boot provides several ways to configure CORS, such as through global configuration, controller-specific configuration, and using filters. Below is an example of global CORS configuration using a Spring configuration class.

2.1 Global CORS Configuration

The global CORS configuration is applied across the entire application. It can be done by defining a bean of type WebMvcConfigurer in a configuration class.

// Import statements
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class CorsConfig {

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**")
                        .allowedOrigins("http://localhost:3000")
                        .allowedMethods("GET", "POST", "PUT", "DELETE")
                        .allowedHeaders("*")
                        .allowCredentials(true);
            }
        };
    }
}

In the above code:

  • addMapping("/**"): Configures CORS to be applied to all endpoints in the application.
  • allowedOrigins("http://localhost:3000"): Specifies the allowed origin for CORS requests. Here, only requests from http://localhost:3000 are allowed.
  • allowedMethods("GET", "POST", "PUT", "DELETE"): Specifies the HTTP methods allowed for CORS requests.
  • allowedHeaders("*"): Allows all headers in CORS requests.
  • allowCredentials(true): Allows sending credentials such as cookies in CORS requests.

Once the global configuration is in place, CORS is enabled for all endpoints across the application.

3. Testing CORS Using MockMvc

MockMvc is a powerful tool for testing Spring MVC applications. It can be used to simulate HTTP requests, including those with CORS configurations. Below is an example of how to test CORS using MockMvc.

3.1 Testing CORS with MockMvc

Let’s create a test class to verify the CORS configuration.

// Import statements
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.options;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@SpringBootTest
@AutoConfigureMockMvc
public class CorsTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void testCorsHeaders() throws Exception {
        mockMvc.perform(options("/api/resource")
                .header("Origin", "http://localhost:3000")
                .header("Access-Control-Request-Method", "GET"))
                .andExpect(status().isOk())
                .andExpect(header().string("Access-Control-Allow-Origin", "http://localhost:3000"))
                .andExpect(header().string("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE"))
                .andExpect(header().string("Access-Control-Allow-Headers", "*"))
                .andExpect(header().string("Access-Control-Allow-Credentials", "true"));
    }
}

In the above test:

  • options("/api/resource"): Simulates an HTTP OPTIONS request to the endpoint /api/resource. OPTIONS requests are typically used by browsers to determine the allowed CORS methods and headers.
  • header("Origin", "http://localhost:3000"): Sets the Origin header to match the allowed origin in the CORS configuration.
  • header("Access-Control-Request-Method", "GET"): Simulates a CORS preflight request for the GET method.
  • andExpect(status().isOk()): Asserts that the response status is 200 OK.
  • andExpect(header().string("Access-Control-Allow-Origin", "http://localhost:3000")): Verifies that the Access-Control-Allow-Origin header is correctly set.
  • andExpect(header().string("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE")): Verifies that the Access-Control-Allow-Methods header is correctly set.
  • andExpect(header().string("Access-Control-Allow-Headers", "*")): Verifies that the Access-Control-Allow-Headers header is correctly set.
  • andExpect(header().string("Access-Control-Allow-Credentials", "true")): Verifies that the Access-Control-Allow-Credentials header is correctly set.

This test ensures that the CORS configuration is correctly applied to the specified endpoint.

3.1.1 Test Output

The expected output for the above test is as follows:

MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = {Access-Control-Allow-Origin=[http://localhost:3000], 
                     Access-Control-Allow-Methods=[GET,POST,PUT,DELETE], 
                     Access-Control-Allow-Headers=[*], 
                     Access-Control-Allow-Credentials=[true]}
     Content type = null
             Body = 
    Forwarded URL = null
   Redirected URL = null

The test output shows that the CORS headers are correctly applied to the response.

4. Conclusion

In this article, we explored how to configure CORS in a Spring Boot application and how to test it using MockMvc. By using the provided code examples, you can ensure that your application correctly handles CORS requests and passes CORS-related tests.

Yatin Batra

An experience full-stack engineer well versed with Core Java, Spring/Springboot, MVC, Security, AOP, Frontend (Angular & React), and cloud technologies (such as AWS, GCP, Jenkins, Docker, K8).
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button