Spring boot 中 Post 映射出现 Cors 错误

ble*_*u83 5 java rest spring cors angular

我有一个带有休息控制器的 Spring boot 应用程序和一个作为前端的 Angular 应用程序。\n目前,它们都在 localhost 中运行,并且启用了 SpringSecurity。\n最初,由于 Cors,我无法从 Angular 向 Spring 发出 getRequest。我将@CrossOrigin 添加到我的restContoller 中,现在我能够执行从Angular 到Spring 的Get 请求。\n现在我在发布请求时遇到了同样的问题。我想从 Angular 向 Spring 发送一些表单数据,但在 Chrome 中总是出现错误。我在这里也添加了@CrossOrigin,但我仍然有问题。\n如果我尝试使用邮递员发送帖子请求,它工作得很好

\n\n

zone.js:3243 从源“http://localhost:4200 ”访问“localhost:8080/rest/contact”处的 XMLHttpRequest已被 CORS 策略阻止:仅协议方案支持跨源请求: http、数据、chrome、chrome 扩展、https。

\n\n

contact.component.ts:51 HttpErrorResponse\xc2\xa0{headers: HttpHeaders, status: 0, statusText: "未知错误", url: "localhost:8080/rest/contact", ok: false,\xc2\xa0\xe2 \x80\xa6}

\n\n

这是我的安全配置:

\n\n
@EnableGlobalMethodSecurity(prePostEnabled = true)\n@Configuration\n@EnableWebSecurity\npublic class SecurityConfig extends WebSecurityConfigurerAdapter {\n\n    @Autowired\n    private CustomUserDetailsService userDetailsService;\n\n    @Override\n    protected void configure (AuthenticationManagerBuilder auth) throws Exception {\n        auth.userDetailsService(userDetailsService)\n        .passwordEncoder(getPasswordEncoder());\n    }\n\n\n    @Override\n    protected void configure(HttpSecurity http) throws Exception {\n        http.cors();\n        http\n                .authorizeRequests()\n                .antMatchers("/admin/**").authenticated()//.hasAnyRole("ADMIN","USER")\n                .and().formLogin().loginPage("/login").permitAll()\n                .and().logout();\n        http.csrf().disable();\n        //http.headers().frameOptions().disable();\n    }\n\n\n    private PasswordEncoder getPasswordEncoder() {\n        return new PasswordEncoder() {\n            @Override\n            public String encode(CharSequence charSequence) {\n                return charSequence.toString();\n            }\n\n            @Override\n            public boolean matches(CharSequence charSequence, String s) {\n\n                return encode(charSequence).equals(s);\n            }\n        };\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

我的 Cors 配置:

\n\n
@Configuration\npublic class CorsConfiguration {\n\n    @Bean\n    public WebMvcConfigurer corsConfigurer() {\n        return new WebMvcConfigurerAdapter() {\n            @Override\n            public void addCorsMappings(CorsRegistry registry) {\n                registry.addMapping("/**");\n            }\n        };\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

我的休息控制器:

\n\n
@RestController()\n@CrossOrigin(origins = "http://localhost:4200/**", maxAge = 3600)\npublic class GymRestController {\n\n    private final GymRepository gymRepository;\n\n    GymRestController (GymRepository gymRepository) {\n        this.gymRepository = gymRepository;\n    }\n\n    @GetMapping("/rest/gyms")\n    public List<Gym> findAll() {\n        return gymRepository.findAll();\n    }\n\n    @PostMapping ("/rest/contact")\n    public void submitContact(@RequestBody ContactForm contactForm) {\n        System.out.println(contactForm);\n\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

和我的角度提交方法

\n\n
  onSubmit() {\n    this.submitted = true;\n\n    if (this.messageForm.invalid) {\n        return;\n    }\n\n    this.success = true;\n\n    this.contactModel.fromName = this.messageForm.get(\'name\').value;\n    this.contactModel.fromMail = this.messageForm.get(\'email\').value;\n    this.contactModel.subject = this.messageForm.get(\'subject\').value;\n    this.contactModel.message = this.messageForm.get(\'message\').value;\n\n    let url = "http://localhost:8080/rest/contact";\n    // let url = "https://cors.io/?localhost:8080/rest/contact"\n    this.http.post(url, this.contactModel).subscribe(\n      res => console.log("success"),\n      error => console.log(error),\n      () => console.log("complete")\n    );\n\n\n  }\n
Run Code Online (Sandbox Code Playgroud)\n\n

我已经尝试了 3 天来使其正常工作,但没有任何运气\n任何帮助将不胜感激

\n

ble*_*u83 5

我终于找到了解决方案。我必须在 Spring Security 中启用 cors 并禁用 csrf

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .cors().and()
            .authorizeRequests()
            .antMatchers("/admin/**").authenticated()//.hasAnyRole("ADMIN","USER")
            .and().formLogin().loginPage("/login").permitAll()
            .and().logout();
    http.csrf().disable();
    http.headers().frameOptions().disable();
}
Run Code Online (Sandbox Code Playgroud)

我必须从控制器中删除@CrossOrigin,并添加以下配置:

@Configuration
public class CorsConfiguration {

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


Gun*_*mar 0

以下是 Spring io 链接: https://spring.io/blog/2015/06/08/cors-support-in-spring-framework

如果您使用 Spring Boot,建议只声明一个 WebMvcConfigurer bean,如下所示:

@Configuration
public class MyConfiguration {

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**");
            }
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以轻松更改任何属性,以及仅将此 CORS 配置应用于特定路径模式:

@Override
public void addCorsMappings(CorsRegistry registry) {
    registry.addMapping("/api/**")
        .allowedOrigins("http://domain2.com")
        .allowedMethods("PUT", "DELETE","POST")
            .allowedHeaders("header1", "header2", "header3")
        .exposedHeaders("header1", "header2")
        .allowCredentials(false).maxAge(3600);
}
Run Code Online (Sandbox Code Playgroud)

在上面,您可以将http://domain2.com替换为您的本地主机或所需的主机/url。