2

I am running an angular frontend with OAuth2 authentication, running on a http-server-spa http server. If i run the Spring Gateway, the Angular app, and the target application on localhost, it works, but if I try to run it with docker-compose, I have a cors error.

application.yml:

cloud:
  gateway:
    default-filters:
      - DedupeResponseHeader=Access-Control-Allow-Origin
    globalcors:
      add-to-simple-url-handler-mapping: true
      corsConfigurations:
        '[/**]':
          allowed-origins: "*"
          allowed-methods: "*"
          allowed-headers: "*"
          allow-credentials: true

GatewayApplication:

@SpringBootApplication
@RestController
@EnableEurekaClient
public class GatewayApplication {

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

    @Bean
    public RouteLocator myRoutes(RouteLocatorBuilder builder) {
        return builder.routes()
                .route(r -> r.path("/hometest")
                        .uri("lb://USER-SERVICE")
                        .id("hometest"))
                .route(r -> r.path("/user/**")
                        .uri("lb://USER-SERVICE")
                        .id("user-service"))
                .route(r -> r.path("/email/**")
                        .uri("lb://EMAIL-SERVICE")
                        .id("email-service"))
                .route(r -> r.path("/login/**")
                        .uri("lb://USER-SERVICE")
                        .id("user-service"))
                .build();
    }
}

CorsConfiguration

@Configuration
public class CorsConfiguration {

    private static final String ALLOWED_HEADERS = "x-requested-with, authorization, Content-Type, Authorization, credential, X-XSRF-TOKEN,token,username,client";
    private static final String ALLOWED_METHODS = "*";
    private static final String ALLOWED_ORIGIN = "*";
    private static final String ALLOWED_EXPOSE = "*";
    private static final String MAX_AGE = "3600";

    @Bean
    public WebFilter corsFilter() {
        return (ServerWebExchange ctx, WebFilterChain chain) -> {
            ServerHttpRequest request = ctx.getRequest();
            if (CorsUtils.isCorsRequest(request)) {
                ServerHttpResponse response = ctx.getResponse();
                HttpHeaders headers = response.getHeaders();
                headers.set("Access-Control-Allow-Origin", ALLOWED_ORIGIN);
                headers.add("Access-Control-Allow-Methods", ALLOWED_METHODS);
                headers.add("Access-Control-Max-Age", MAX_AGE);
                headers.add("Access-Control-Allow-Headers", ALLOWED_HEADERS);
                headers.add("Access-Control-Expose-Headers", ALLOWED_EXPOSE);
                headers.add("Access-Control-Allow-Credentials", "true");
                if (request.getMethod() == HttpMethod.OPTIONS) {
                    response.setStatusCode(HttpStatus.OK);
                    return Mono.empty();
                }
            }
            return chain.filter(ctx);
        };
    }
}

docker-compose.yml:

version: '3'
services:

  user-db:
    image: mysql:8
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: ThesisPass01!
    volumes: 
            - ./init:/docker-entrypoint-initdb.d
    ports:
      - "3306:3306"
    networks:
    - network

  gateway:
    build: gateway
    restart: always
    ports:
      - "8080:8080"
    depends_on:
      - eureka
    environment: 
      - eureka.client.serviceUrl.defaultZone=http://eureka:8761/eureka
    networks:
     - network

  user-service:
    build: user-service
    restart: always
    ports:
      - "8090:8090"
    depends_on:
      - user-db
      - eureka
    environment:
      - DATABASE_HOST=user-db
      - DATABASE_USER=springuser
      - DATABASE_PASSWORD=pass
      - DATABASE_NAME=test_db
      - DATABASE_PORT=3306
      - spring.datasource.username=springuser
      - spring.datasource.password=pass
      - spring.datasource.url=jdbc:mysql://user-db:3306/test_db
      - eureka.client.serviceUrl.defaultZone=http://eureka:8761/eureka
    networks:
     - network

  eureka:
    build: discovery-service
    expose:
      - "8761"
    ports: 
      - "8761:8761"
    networks:
      - network

  frontend:
    build: ./frontend/fixit-frontend
    #run: "http-server-spa dist/fixit-frontend index.html 4200"
    ports:
      - "4200:4200"
    networks:
      - network

networks:
  network:
    driver: bridge

And the error I get when i run it with docker-compose up:

Access to XMLHttpRequest at 'http://localhost:8080/user/profile' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

What could be the issue here? Thanks in advance!

Daniel
  • 29
  • 4

1 Answers1

0

Spring documentation tells its enough to declare such configuration in application.yml

spring:
  cloud:
    gateway:
      globalcors:
        corsConfigurations:
          '[/**]':
            allowedOrigins: "*"
            allowedMethods:
            - GET
            - POST

Also you can define your custom CorsConfiguration :

@Configuration
public class CorsConfiguration{
    @Bean
    public CorsWebFilter corsWebFilter() {
    
        final CorsConfiguration corsConfig = new CorsConfiguration();
        corsConfig.setAllowedOrigins(Collections.singletonList("*"));
        corsConfig.setMaxAge(3600L);
        corsConfig.setAllowedMethods(Arrays.asList("GET", "POST"));
        corsConfig.addAllowedHeader("*");
    
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", corsConfig);
    
        return new CorsWebFilter(source);
    }  
}

Source :Spring Gateway Request blocked by CORS (No Acces0Control-Allow-Orgin header)

Sai Ram
  • 63
  • 1
  • 8