spring-cloud-gateway icon indicating copy to clipboard operation
spring-cloud-gateway copied to clipboard

spring cloud gateway version 3 CORS Origin policy problem can't be modify

Open SubhamKrGuptaDev opened this issue 2 years ago • 11 comments

I think this is a bug because I tried every solution that I get on the internet but it does not work. still CORS Origin policy error I'm getting

It always shows a CORS origin problem or 403 error but in Postman works perfectly.

If you know the solution please reply or else please fix this bug I think this is a bug or I'm going something wrong

application.yml file

server: port: 9999

spring: cloud: gateway: globalcors: add-to-simple-url-handler-mapping: true

    corsConfigurations:
      '[/**]':
        allowedOrigins: "*"
        allowedMethods:
          - GET
          - POST
          - PUT
          - DELETE
          - PATCH
        allowedHeaders:
          - "Origin"
          - "Content-Type"
          - "Accept"
          - "Authorization"
          - "User-Key"
          - "Request-Tracker"
          - "Session-Tracker"
          - "X-XSRF-TOKEN"
          - "X-IBM-CLIENT-ID"
          - "Message-ID"
          - "X-IBM-CLIENT-SECRET"
  default-filters:
    - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin, RETAIN_FIRST


  routes:
    - id: ADMIN-SERVICE
      uri: https://example
      predicates:
        - Path=/v1.0.0/registration/example


    - id: ADMIN-SERVICE
      uri:  https://example
      predicates:
        - Path=/v1.0.0/registration/example/**
      filters:
        - AuthenticationFilter

  httpclient:
    ssl:
      useInsecureTrustManager: true

AuthenticationFilter.java

package com.api.filter;

import com.api.exception.MissingAuthorizationHeaderException; import com.api.exception.UnauthorizedAccessException; import com.api.util.JwtUtil; import lombok.extern.slf4j.Slf4j; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.gateway.filter.GatewayFilter; import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory; import org.springframework.http.HttpHeaders; import org.springframework.stereotype.Component; import reactor.core.publisher.Mono;

@Slf4j @Component public class AuthenticationFilter extends AbstractGatewayFilterFactory<AuthenticationFilter.Config> {

@Autowired
private RouteValidation routeValidation;

@Autowired
private JwtUtil jwtUtil;

public AuthenticationFilter() {
    super(Config.class);
    log.info("AuthenticationFilter() -> | ");
}

@Override
public GatewayFilter apply(Config config) {

    log.info("============== Apply Method Start ==============");
    log.info("apply(Config) -> | Config : {}", config);

    GatewayFilter bearer = (exchange, chain) -> {

        log.info("apply(Config) -> | Exchange : {} | Chain : {}", exchange, chain);

        if (routeValidation.isSecured.test(exchange.getRequest())) {
            log.info("apply(Config) -> | Route Validation isSecured : ");
            //header contains token or not
            log.info("apply(Config) -> | HttpHeader Check : {}", HttpHeaders.AUTHORIZATION);

            if (!exchange.getRequest().getHeaders().containsKey(HttpHeaders.AUTHORIZATION)) {
                log.error("apply(Config) -> | MissingAuthorizationHeaderException Throw :");
                throw new MissingAuthorizationHeaderException();
            }

            log.info("apply(Config) -> | authorization header present");
            String authHeader = exchange.getRequest().getHeaders().get(HttpHeaders.AUTHORIZATION).get(0);
            log.info("apply(Config) -> | AuthHeader : {}", authHeader);

            if (authHeader != null && authHeader.startsWith("Bearer ")) {
                authHeader = authHeader.substring(7);
                log.info("apply(Config) -> | After Delete AuthHeader : {}", authHeader);
            }

            try {

                log.info("apply(Config) -> | Try to validateToken");
                jwtUtil.validateToken(authHeader);

            } catch (Exception e) {
                log.error("apply(Config) -> | Exception Message : {} | Exception Cause : {}", e.getMessage(), e.getCause());
                log.error("apply(Config) -> | UnauthorizedAccessException Throw | invalid access...");
                throw new UnauthorizedAccessException();
            }

        }

        Mono<Void> filter = chain.filter(exchange);
        log.info("apply(Config) -> | Mono<Void> : {}", filter);

        return filter;
    };

    log.info("apply(Config) -> | GatewayFilter Object : {}", bearer);
    log.info("============== Apply Method End ==============");
    return bearer;
}

public static class Config {
    public Config() {
        log.info("Config() -> | Create Object Config class of sub class AuthenticationFilter extends by AbstractGatewayFilterFactory");
    }
}

}

SubhamKrGuptaDev avatar May 06 '23 06:05 SubhamKrGuptaDev

We had the same issue in our project. No matter what we try, our requests get always rejected because of CORS.

ksilz avatar May 19 '23 09:05 ksilz

@SubhamKrGuptaDev I think you're missing the OPTIONS method. With CORS, the browser sends a so-called preflight request. That's an OPTIONS request.

ksilz avatar May 19 '23 10:05 ksilz

Very similar observation(s) here at my end - Looks like globally defined CORS policy applies to dynamically specified routes (both in an application yaml file), where the same does not apply to our REST Controller(s) within the same application...

Only workaround so far that seems to work, is when I use the @CrossOrigin annotation directly on Controller Class level, resp. as described here: https://www.baeldung.com/spring-webflux-cors.

So now I'm really not sure if there is a bug or if the observed behavior is by intention - was able to reproduce in both Spring Cloud release train 2022 and 2021.

polster avatar May 21 '23 20:05 polster

The Issue is Version Version is 3.0 and the API gateway 3.0 version has some bugs if you want to use API Gateway then the below 3.0 versions are working fine you can try it once.

SubhamDeveloperGupta avatar Jun 12 '23 05:06 SubhamDeveloperGupta

any news on this topic? I have the same problems

ducanh2110 avatar Jul 27 '23 07:07 ducanh2110

I have fixed it! Now it works !!!! Just copy it in order:

server:
  port: 2620
  address: 25.68.201.55
eureka:
  client:
    fetch-registry: true
    register-with-eureka: true
    service-url:
      defaultZone: http://localhost:8761/eureka
spring:
  application:
    name: Api GateWay
  cloud:
    gateway:
      globalcors:
        add-to-simple-url-handler-mapping: true
        corsConfigurations:
          '[/**]':
            allowedOrigins: "http://127.0.0.1:5500"
            allowedHeaders:
              - "Origin"
              - "Content-Type"
              - "Accept"
              - "Authorization"
              - "Referer"
            allowedMethods:
              - POST
              - GET
              - OPTIONS
      routes:
        - id: Customer Login
          uri: http://localhost:8080
          predicates:
            - Path=/api/v1/auth/login
        - id: Customer Registration
          uri: http://localhost:8080
          predicates:
            - Path=/api/v1/auth/register
        - id: Customer Google login
          uri: http://localhost:8080
          predicates:
            - Path=/api/v1/auth/google/login
        - id: Confirm email
          uri: http://localhost:8081
          predicates:
            - Path=/confirm
      default-filters:
        - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin, RETAIN_FIRST

n0rb33rt avatar Aug 11 '23 09:08 n0rb33rt

@n0rb33rt are you using latest spring-boot 3.2.0 and spring cloud 2023.0.0 with this working? What version was this successful with?

StevenPG avatar Dec 11 '23 00:12 StevenPG

I also encounter same issue with the below setting. 7 months has passed, no engineer is assigned to look at this issue? Currently using spring boot 3.2.1

spring:
  cloud:
    gateway:
       routes:
        - id: multiplication
          uri: http://localhost:8080/
          predicates:
            - Path=/challenges/**,/attempts,/attempts/**,/users/**
        - id: gamification
          uri: http://localhost:8081/
          predicates:
            - Path=/leaders
       globalcors:
        cors-configurations:
          '[/**]':
            allowedOrigins: "http://localhost:3000"
            allowedHeaders: "*"
            allowedMethods:
              - "GET"
              - "POST"
              - "OPTIONS"
       default-filters:
        - DedupeResponseHeader=Access-Control-Allow-Origin Access-Control-Allow-Credentials, RETAIN_UNIQUE

hannah23280 avatar Dec 24 '23 02:12 hannah23280

I also notice that in 3.2.1, the starter is org.springframework.cloud:spring-cloud-starter-gateway-mvc In 3.1.7, it is org.springframework.cloud:spring-cloud-starter-gateway (without the -mvc)

Not sure if this difference is related to the CORS origin issue..

hannah23280 avatar Dec 24 '23 02:12 hannah23280

I faced the same issue, but as n0rb33rt mentioned the below configuration worked for me, add-to-simple-url-handler-mapping: true As also mentioned in Spring Doc

abhishekchatterjee-rss avatar Jan 12 '24 11:01 abhishekchatterjee-rss

@hannah23280 It works with spring boot 3.2.1 Do not enable cors on your microservices. Just enable it on the gateway.

mathias8dev avatar Jan 15 '24 01:01 mathias8dev

It looks like things have been resolved. Feel free to comment if not and we can reopen to discuss.

spencergibb avatar Mar 12 '24 02:03 spencergibb

@hannah23280Funciona con Spring Boot 3.2.1. No habilite cors en sus microservicios. Simplemente habilitelo en la puerta de enlace. Ugh, thank you very much because I didn't see this post before, the official documentation was always a little correct, in my case I only did this and don't enable @crossorigin for any microservices

spring:
  application:
    name: servicio-api-gateway
  cloud:
    gateway:
      globalcors:
        add-to-simple-url-handler-mapping: true
        corsConfigurations:
          '[/**]':
            allowedOrigins: "http://127.0.0.1:5501"
            allowedHeaders: "*" 
            allowedMethods:
              - POST
              - GET
              - OPTIONS
              - PUT 
              - DELETE
     
server:
  port: 10450

MateoRodriguez0 avatar May 08 '24 02:05 MateoRodriguez0

I have this configuration, it works great with all the methods but delete, what can I add to this to make it work with the delete method: spring: application: name: msvc-gateway cloud: gateway: globalcors: add-to-simple-url-handler-mapping: true cors-configurations: '[/**]': allowed-origins: "" allowedMethods: - "GET" - "POST" - "PUT" - "PATCH" - "DELETE" - "OPTIONS" allowed-headers: "" allow-credentials: false

JuanPabaz avatar Jul 18 '24 13:07 JuanPabaz

is there anyone who says it is working does not share small code with us :)?

teyyub avatar Jul 29 '24 16:07 teyyub