Google App Engine CORS Error – Java Server Solution

corsgoogle-app-enginejavaspringboot

I have two apps.

Frontend(Angular) running on Firebase

Backend Spring Boot (Java11) running on App Engine

Got this error while trying to reach any endpoints in app engine "Access 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"

An interesting thing that, everything works fine in my local machine. No issues with cors. So, I guess the problem is in the configuration of app engine or smth else.

Could someone help me to solve this problem? I've already spent a lot of time trying to fix it. Already read a lot of stackoverflow similar issues. The last one: How to configure CORS in a Spring Boot + Spring Security application?

Can't find anything helpful in google docs.

app.yaml file

runtime: java11
instance_class: F4
vpc_access_connector:
  name: projects/<project_id>/locations/<location>/connectors/<connectors_name>

Here my config files:

CorsFilterConfig.java

@Configuration
public class CorsFilterConfig {
    
    @Value("${allowed-origin}")
    private String allowedOrigin;

    @Bean
    public FilterRegistrationBean<CorsFilter> simpleCorsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.setAllowedOrigins(Collections.singletonList(allowedOrigin));
        config.setAllowedMethods(Collections.singletonList("*"));
        config.setAllowedHeaders(Collections.singletonList("*"));
        source.registerCorsConfiguration("/**", config);
        FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(new CorsFilter(source));
        bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
        return bean;
    }
}

allowedOrigin points to the https://<firebase.domain>

SecurityConfig.java

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .cors()
                .and()
                .csrf().disable()
                .authorizeRequests().anyRequest().authenticated()
                .and()
                .oauth2Login()
                .and()
                .oauth2ResourceServer().jwt();

Endpoint example

@RestController
@RequestMapping("/test")
@AllArgsConstructor
public class TestController {

    @GetMapping
    public String hello() {
        return "hello world";
    }
}

I guess that you can't use app.yaml to control HTTP headers for dynamic
handlers. It is only applicable for static content

That's why this config fails to deploy with this error
"Unexpected attribute "http_headers" for mapping type script."

runtime: java11
instance_class: F4
vpc_access_connector:
  name: projects/<project_id>/locations/<location>/connectors/<connectors_name>
handlers:
  - url: /.*
    script: auto
    http_headers:
      Access-Control-Allow-Origin: *

Best Answer

The issue is that the CORS needs to be allowed on the app engine app.

This can be done on the app.yaml by adding a handler to include the CORS headers like this:

runtime: java11
instance_class: F4
vpc_access_connector:
  name: projects/<project_id>/locations/<location>/connectors/<connectors_name>
- url: /.*
  script: auto
  http_headers:
    Access-Control-Allow-Origin: *

This will allow the CORS calls to come from any domain, if you want to have it more spefic to only allow your firebase app you can change the * to the firebase App URL

Related Topic