Search code examples
angularspring-securitykeycloakspring-security-oauth2spring-cloud-gateway

Spring Cloud Gateway Preflight Cors Error with Angular


I'm trying to use spring cloud gateway with spring security and trying to call the rest API through angular but I'm getting following error

Access to XMLHttpRequest at 'http://localhost:9090/api/v1/publishers/?pageNo=1&pageSize=10&sort=name,desc&sort=city,desc' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request.

According to the documentation https://cloud.spring.io/spring-cloud-gateway/multi/multi__cors_configuration.html

I have to add globalcors in application yaml file.

here is my complete yaml file.

server:
  port: 9090
keycloak-client:
  server-url: http://keycloak-url:8080/auth
  realm: dev
spring:
  application:
    name: gateway
  security:
    oauth2:
      client:
        provider:
          keycloak:
            issuer-uri: ${keycloak-client.server-url}/realms/${keycloak-client.realm}
            user-name-attribute: preferred_username
        registration:
          keycloak:
            client-id: cei-backend
            client-secret: f4d3242b-1fee-4dab-a491-d91ac51d637f
  cloud:
    gateway:
      default-filters:
        - TokenRelay
      globalcors:
        cors-configurations:
          '[/**]':
            allowedOrigins: "http://localhost:4200"
            allowedHeaders: "*"
            allowedMethods:
            - GET
            - POST
            - DELETE
            - PUT
      routes:
        - id: publisher_route
          uri: http://localhost:8000
          predicates:
            - Path=/api/v1/publishers/**
          filters:
            - RemoveRequestHeader=Cookie        
logging:
  level:
    org.springframework.cloud.gateway: DEBUG
    reactor.netty: DEBUG

Following is my security config file

@Configuration
public class SecurityConfig {

    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http,
                                                            ReactiveClientRegistrationRepository clientRegistrationRepository) {
        // Authenticate through configured OpenID Provider
        http.oauth2Login();
        // Also logout at the OpenID Connect provider
        http.logout(logout -> logout.logoutSuccessHandler(new OidcClientInitiatedServerLogoutSuccessHandler(
                clientRegistrationRepository)));
        // Require authentication for all requests
        http.authorizeExchange().anyExchange().authenticated();
        // Allow showing /home within a frame
        http.headers().frameOptions().mode(Mode.SAMEORIGIN);
        // Disable CSRF in the gateway to prevent conflicts with proxied service CSRF
        http.csrf().disable();

        return http.build();
    }

I'm calling this API from angular but I'm getting CORS error on the preflight request. I have tried everything but no idea where I'm making a mistake. Any idea?


Solution

  • I solved it by moving Angular App behind the API gateway and added the following code in the API Gateway and Microservice

    In API Gateway

    http.cors();
    

    In Microservice

    @Configuration
    @EnableWebMvc
    public class RestServiceCorsApplication implements WebMvcConfigurer {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**");
        }
    }