'CORS header ‘Access-Control-Allow-Origin’ missing). Status code: 403

I have a microservice-based backend in SpringBoot. Hereby key API gateway configurations:

@Override
    protected void configure(HttpSecurity http) throws Exception {

        http.csrf().disable().cors().and()
                .authorizeRequests()
                .antMatchers("/auth/api/v1/**").permitAll()
                .antMatchers(HttpMethod.POST, "/movies/api/v1/save").access("hasAuthority('USER')")
                .antMatchers(HttpMethod.GET, "/movies/api/v1/**").access("hasAuthority('USER')")
                .anyRequest()
                .authenticated()
                .and()
                .exceptionHandling()
                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        http.addFilterBefore(filter, UsernamePasswordAuthenticationFilter.class);
    }
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

        response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me");

        String authorizationHeader = request.getHeader("Authorization");

        if (authorizationHeader != null) {
            String token = null;
            String email = null;

            if (authorizationHeader.startsWith("Bearer ")) {
                token = authorizationHeader.substring(7);
                try {
                    email = jwtUtil.extractEmail(token);
                } catch (Exception e) {
                    response.sendError(401);
                }
            }

            if (email != null && SecurityContextHolder.getContext().getAuthentication() == null) {

                UserDetails userDetails = service.loadUserByUsername(email);

                if (jwtUtil.validateToken(token, userDetails)) {

                    UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =
                            new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                    usernamePasswordAuthenticationToken
                            .setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                    SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
                }

            }

        } else {
            // If there is no token, check if the route is whitelisted
            String requestURI = request.getRequestURI();
            String requestMethod = request.getMethod();
            if (!checkRoute(requestURI, requestMethod)) {
                response.sendError(401);
            }

        }
        filterChain.doFilter(request, response);
    }

The AuthService controller has a @CrossOrigin(origins = "*", allowedHeaders = "*") annotation.

Now, everything works properly through Postman. However, auth requests from my ReactJS client throw CORS errors. This is from Firefox:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8080/auth/api/v1/login. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). Status code: 403.

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

And this is from Chrome:

Access to XMLHttpRequest at 'http://localhost:8080/auth/api/v1/login' from origin 'http://localhost:3000' 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.
xhr.js:220          POST http://localhost:8080/auth/api/v1/login net::ERR_FAILED

And these are the logs in the gateway:

2022-05-19 15:15:46.081 DEBUG 3536 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy        : Securing OPTIONS /auth/api/v1/login
2022-05-19 15:15:46.081 TRACE 3536 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy        : Invoking WebAsyncManagerIntegrationFilter (1/12)
2022-05-19 15:15:46.082 TRACE 3536 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy        : Invoking SecurityContextPersistenceFilter (2/12)
2022-05-19 15:15:46.082 DEBUG 3536 --- [nio-8080-exec-4] s.s.w.c.SecurityContextPersistenceFilter : Set SecurityContextHolder to empty SecurityContext
2022-05-19 15:15:46.082 TRACE 3536 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy        : Invoking HeaderWriterFilter (3/12)
2022-05-19 15:15:46.082 TRACE 3536 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy        : Invoking CorsFilter (4/12)
2022-05-19 15:15:46.083 TRACE 3536 --- [nio-8080-exec-4] o.s.s.w.header.writers.HstsHeaderWriter  : Not injecting HSTS header since it did not match request to [Is Secure]
2022-05-19 15:15:46.084 DEBUG 3536 --- [nio-8080-exec-4] s.s.w.c.SecurityContextPersistenceFilter : Cleared SecurityContextHolder to complete request


Sources

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

Source: Stack Overflow

Solution Source