'CORS requests blocked when hitting k8s service exposing Spring Boot API

I currently have an Angular application trying to call a Spring Boot application with simple HTTP queries. Both of the applications are running on their own pod in K3S. My Spring Boot app is exposed through a service and can be reached from the Angular's pod via curl queries. Here's the service definition of my Spring Boot app:

apiVersion: v1
kind: Service
metadata:
  name: elements-recorder-api-ip
spec:
  ports:
    - port: 8080
      targetPort: 8080
  selector:
    app: elements-recorder-api

From the angular pod, I can call it with curl http://elements-recorder-api-ip:8080/api/articles.

My Angular app is exposed with a service of type NodePort to be reachable outside of the cluster:

apiVersion: v1
kind: Service
metadata:
  name: elements-recorder-front-service
spec:
  type: NodePort
  selector:
    app: elements-recorder-front
  ports:
    - port: 80
      targetPort: 80
      nodePort: 31111

However, when I access my Angular app, I face an error that seems CORS related. With Firefox, I get the following error message:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://elements-recorder-api-ip:8080/api/resource/. (Reason: CORS request did not succeed). Status code: (null).

With Chrome, I simply get the following one:

GET http://elements-recorder-api-ip:8080/api/resource/ net::ERR_NAME_NOT_RESOLVED

Currently, my CORS configuration is wide-open on Spring Security:

@Bean
public WebMvcConfigurer corsConfigurer() {
    return new WebMvcConfigurer() {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**")
                    .allowedOrigins("*")
                    .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS");
        }
    };
}

I also tried by simply disabling CORS, without success.

Here's the url I use in my Angular app to call my backend:

export const environment = {
  production: true,
  serverUrl: 'http://elements-recorder-api-ip:8080/api',
  allowedDomain: 'elements-recorder-api-ip:8080'
};

Based on what I read to troubleshoot that, I suspect it to be a Nginx configuration issue. Therefore, after multiple tries with the proxy_pass method, I tried to copy this "Wide-open CORS config":

server {
  listen 80;

  #
  # Wide-open CORS config for nginx
  #
  location / {
       root   /usr/share/nginx/html;
       index  index.html;
       expires -1;
       add_header Pragma "no-cache";
       add_header Cache-Control "no-store, no-cache, must-revalidate, post-check=0, pre-check=0";
       try_files $uri$args $uri$args/ $uri $uri/ /index.html =404;

       if ($request_method = 'OPTIONS') {
          add_header 'Access-Control-Allow-Origin' '*';
          add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
          #
          # Custom headers and headers various browsers *should* be OK with but aren't
          #
          add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
          #
          # Tell client that this pre-flight info is valid for 20 days
          #
          add_header 'Access-Control-Max-Age' 1728000;
          add_header 'Content-Type' 'text/plain; charset=utf-8';
          add_header 'Content-Length' 0;
          return 204;
       }
       if ($request_method = 'POST') {
          add_header 'Access-Control-Allow-Origin' '*' always;
          add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
          add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
          add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
       }
       if ($request_method = 'GET') {
          add_header 'Access-Control-Allow-Origin' '*' always;
          add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
          add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
          add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
       }
  }

#   location ~ ^/api {
#     proxy_pass http://elements-recorder-api-ip:8080;
#   }
}

Still without success, unfortunately. As you can see commented out, I tried to use proxy_pass as I saw it somewhere else, but it still raises the same error.

One thing that surprises me however, is that I changed the port of the service exposing my API, and the error doesn't change. I find this weird, as I thought that my query was at least reaching my backend but was refused, due to CORS policy.

At the moment, all my tries to resolve the issue have yield the same error, so I could be completely mistaken, but I think it's Nginx related.

Here's my angular repo And here's my Spring Boot repo



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source