Enterprise Java

Configure CORS Policy for Spring Cloud Gateway

Cross-Origin Resource Sharing (CORS) is a mechanism that allows web applications hosted on one domain to interact with resources hosted on a different domain. By default, web browsers block such cross-origin requests for security reasons. However, with CORS, servers can explicitly allow specific origins, headers, and methods. In this article we will investigate how to configure CORS policy for Spring Cloud Gateway.

Spring Cloud Gateway is a popular API Gateway solution built on Spring Boot and Project Reactor. It provides a way to route and filter requests, adding features like rate limiting, path rewriting, and CORS handling to modern microservices architectures.

Properly configuring a CORS policy in Spring Cloud Gateway ensures that client applications, such as single-page applications (SPAs), can securely access APIs hosted on different domains.

1. Code Example

Here is a code example that uses Spring Cloud gateway to route requests and configure a CORS configuration. Before exploring the code, make sure to include the following dependencies in your pom.xml file.

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
</dependencies>

1.1 Create a Main class

package com.example.gateway;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }
}

1.1.1 Code explanation

The code defines the main class of a Spring Boot application using the @SpringBootApplication annotation, which serves as a convenience annotation combining three essential annotations:
@Configuration (for declaring Java-based configuration), @EnableAutoConfiguration (for enabling Spring Boot’s auto-configuration mechanism), and @ComponentScan (for scanning components in the package and its sub-packages).

The GatewayApplication class includes the main method, which serves as the entry point for the application. Inside the main method, the static SpringApplication.run() method is called, passing the GatewayApplication.class and args as parameters.
This method initializes the Spring application context, starts the embedded server (e.g., Tomcat or Netty), and bootstraps the entire Spring Boot application.

By running this class, the Spring Boot application is launched, enabling it to act as the gateway in a microservices architecture, handling incoming requests, routing them to appropriate backend services, and applying filters like the CORS policy.

1.2 Create a Configuration class

package com.example.gateway.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;

@Configuration
public class CorsConfig {

    @Bean
    public CorsWebFilter corsWebFilter() {
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedOrigin("*"); // Allow all origins
        config.addAllowedMethod("*"); // Allow all HTTP methods
        config.addAllowedHeader("*"); // Allow all headers
        config.setAllowCredentials(true); // Allow credentials

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);

        return new CorsWebFilter(source);
    }
}

Note that a controller is not strictly required in this article, as the primary focus is on configuring the CORS policy in Spring Cloud Gateway rather than setting up a full backend API. However, you can add a mock backend service that is exposed at the URL /api/data and runs on port 8081.

@RestController
@RequestMapping("/api")
public class BackendController {

    @GetMapping("/data")
    public String getData() {
        return "Hello from Backend Service!";
    }
}

1.2.1 Code explanation

The CorsConfig class is annotated with @Configuration, indicating that it is a Spring configuration class. This class defines a bean for configuring Cross-Origin Resource Sharing (CORS) in the application.

The corsWebFilter method is annotated with @Bean, making it a Spring-managed bean. It creates and returns a CorsWebFilter, which is a reactive filter for handling CORS requests in Spring WebFlux applications.

Inside the method, a CorsConfiguration object is instantiated and configured:

  • config.addAllowedOrigin("*");: Allows requests from all origins. This is useful for development but should be restricted to specific origins in production for security reasons.
  • config.addAllowedMethod("*");: Permits all HTTP methods, such as GET, POST, PUT, and DELETE.
  • config.addAllowedHeader("*");: Allows all HTTP headers to be sent in the request.
  • config.setAllowCredentials(true);: Enables the inclusion of credentials like cookies in cross-origin requests.

A UrlBasedCorsConfigurationSource object is created to map the CORS configuration to specific URL patterns. The source.registerCorsConfiguration("/**", config); line applies the CORS policy to all incoming requests (denoted by /**).

Finally, a CorsWebFilter is created using the configured UrlBasedCorsConfigurationSource, ensuring that all requests passing through the application are subject to the defined CORS rules.

This configuration ensures that the application can handle cross-origin requests securely and flexibly, which is critical when serving APIs to frontend applications hosted on different domains.

1.3 Updating Application yml

spring:
  cloud:
    gateway:
      routes:
        - id: example-service
          uri: http://localhost:8081
          predicates:
            - Path=/api/**

server:
  port: 8080

1.3.1 Properties explanation

The provided configuration snippet is for setting up Spring Cloud Gateway and defining routing rules for incoming requests. Under spring.cloud.gateway.routes, a route is defined with the following properties:

  • id: example-service: This is a unique identifier for the route. It is used to refer to this specific route configuration within the application.
  • uri: http://localhost:8081: This specifies the target URI for the route. Any request matching the specified predicate will be forwarded to this URI. In this case, requests will be routed to localhost:8081, which is presumably a backend service running on port 8081.
  • predicates:: This defines the conditions under which the route is triggered. In this case, the predicate is Path=/api/**, meaning that any incoming request with a path starting with /api/ will be routed to the specified URI (i.e., http://localhost:8081).

Finally, the server.port: 8080 property specifies the port on which the Spring Boot application (in this case, Spring Cloud Gateway) will run. The application will listen for incoming requests on port 8080.

2. Run the code

To run the Spring Boot application, ensure that you have Maven installed on your system. Navigate to the project directory in your terminal and execute the command mvn spring-boot:run. This will start the application, and the embedded web server will listen for requests on the port specified in the application.properties file (default is 8080).

Once the application is running, you can test the CORS policy using tools like Postman or your web browser’s developer tools. Ensure that the correct CORS headers are returned for cross-origin requests.

  • Make a GET request to http://localhost:8080/api/data from a client (e.g., a browser or Postman).
  • The request will be routed through the gateway, which applies the CORS policy, and forwarded to the backend service running at http://localhost:8081/api/data.
  • The backend service should respond with a message, such as "Hello from Backend Service!".

3. Conclusion

Configuring a CORS policy in Spring Cloud Gateway is essential for enabling secure and seamless communication between client applications and backend services. By following the steps outlined in this article, you can ensure your API Gateway is CORS-compliant while maintaining security and flexibility.

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