0

Assume that Project is our POJO class. Following function provides to delete a row from database. It is successfully working with POSTMAN requests.

@RestController
@RequestMapping(value = "/project")
@CrossOrigin
public class ProjectController {

    private final ProjectServiceImpl projectServiceImpl;

    ------------
    @DeleteMapping
    @RequestMapping("/delete/{id}")
    public ResponseEntity<Boolean> deleteProject(@PathVariable Long id) {
        boolean result = projectServiceImpl.delete(id);
        return ResponseEntity.ok(result);
    }
    ------------
}

But requests from Angular project are rejecting with 403 message. And following message is appearing in console screen.

Angular error without pre-flight

After some searches. I learned, the application have to answer pre-flight requests with 200. To provide this, following function was added to controller.

@GetMapping
@RequestMapping("/delete/{id:[0-9]+}")
public ResponseEntity.BodyBuilder retreive(@PathVariable Long id) {
    return ResponseEntity.ok();
}

I used regex for request mapping because without it Spring Framework throws /project/delete/{id} already mapped with another function. Angular get its 200OK for pre-flight request with this way. But the application response is 406 for delete operation. Angular is sending http://localhost:8080/project/delete/2 url to the application. If I send same link without have a function for CORS. Row has id with 2 will delete successfully. Am I missing something?

Console error despite have a CORS support

Sources:

Why Angular sending OPTIONS message before DELETE

How to add CORS support to Spring Boot application

To implement server side proxy: proxy.conf.json

{
  "/project/**": {
    "target": "http://localhost:8080",
    "secure": false
  }
}

modified section in angular.json

    "serve": {
      "builder": "@angular-devkit/build-angular:dev-server",
      "options": {
        "browserTarget": "issue-management:build",
        "proxyConfig": "proxy.conf.json"
      },

and Angular project started with ng serve --proxy-config proxy.conf.json but result didn't change. Plus, suggestions in this article applied, again result didn't change.

Kerim
  • 115
  • 2
  • 12

2 Answers2

1

Your applications are running on two different ports, that causing the CORS issue.

Add the proxy(file proxy.conf.json) in your Angular application.

{
    "/project/**": {
        "target": "http://localhost:8080",
        "secure": false
    }
}

and run this ng serve --proxy-config proxy.conf.json

Refference Angular doc


Update:

@Bean
public WebMvcConfigurer corsConfigurer() {
    return new WebMvcConfigurer() {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**")
            .allowedMethods("*")
            .allowedOrigins("http://localhost:4200");
        }
    };
}

worked, For some reason Angular proxy is not working

Pavan Kumar Jorrigala
  • 3,085
  • 16
  • 27
1

If you are using spring security use the following:

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            // by default uses a Bean by the name of corsConfigurationSource
            .cors(withDefaults())
            ...
    }

    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("https://example.com"));
        configuration.setAllowedMethods(Arrays.asList("GET","POST"));
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }
}

See spring documentation: https://docs.spring.io/spring-security/site/docs/current/reference/html5/#cors

Global configuration:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Value("${cors.origins.urls}")
    public String allowedOrigins;

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedMethods("GET", "POST", "PUT", "DELETE")
                .allowedOrigins(allowedOrigins.split(","));

    }
}
  • No I'm not using Spring Security. – Kerim Mar 14 '20 at 15:52
  • sorry, are you using or not using spring security? – Gloria Figueroa Mar 14 '20 at 15:54
  • can you add the origins parameter to the @CrossOrigin in ProjectController, for example: @CrossOrigin(origins = "https://localhost:4200/project:1") (with the http it is removed in my comment) – Gloria Figueroa Mar 14 '20 at 16:02
  • I have added `@CrossOrigin(origins = "http://localhost:4200/project")` to my controller. POSTMAN requests working fine but Angular behaviour didn't change. – Kerim Mar 14 '20 at 16:48
  • I just added the global configuration above, can you try with that? remove the local @CrossOrigin annotation and comment the retrieve method. – Gloria Figueroa Mar 14 '20 at 17:19
  • btw which version of spring are you using? – Gloria Figueroa Mar 14 '20 at 17:40
  • `@CrossOrigin` already top of class. As far as I understand you mean move the annotation from top of function to class. I'm trying all suggestions with `retreive` method and without it. Then I answer. BTW spring boot version is "2.2.4.RELEASE" – Kerim Mar 14 '20 at 17:49