Java Spring 控制器拒绝除 GET 之外的所有请求
Posted
技术标签:
【中文标题】Java Spring 控制器拒绝除 GET 之外的所有请求【英文标题】:Java Spring controler refuses all requests expect GET 【发布时间】:2020-07-21 02:37:41 【问题描述】:我正在开发带有 Angular 前端的 Java Spring 应用程序,但我遇到了没有你的帮助我无法解决的问题。当我从 Angular 向 Java 发出请求时,只有 GET 会通过,但 POST、DELETE 和 POST 会返回以下错误
从源“http://localhost:4200”访问“http://localhost:8080/patient”处的 XMLHttpRequest 已被 CORS 策略阻止:请求的资源上不存在“Access-Control-Allow-Origin”标头。
控制器
@Controller
@RequestMapping("/patient")
@CrossOrigin(origins = "*", maxAge = 3600)
public class PatientController
private PatientService patientService;
@Autowired
public PatientController(PatientService patientService)
this.patientService = patientService;
@GetMapping
public ResponseEntity<Iterable<Patient>> getPatient()
return new ResponseEntity<>(patientService.findAll(), HttpStatus.OK);
@PostMapping
public ResponseEntity<Iterable<Patient>> postPatient()
return new ResponseEntity<>(patientService.findAll(), HttpStatus.OK);
@PutMapping
public ResponseEntity<Iterable<Patient>> putPatient()
return new ResponseEntity<>(patientService.findAll(), HttpStatus.OK);
@DeleteMapping
public ResponseEntity<Iterable<Patient>> deletePatient()
return new ResponseEntity<>(patientService.findAll(), HttpStatus.OK);
角度服务
getPatients()
this.http.post(AppComponent.apiUrl + '/patient', this.httpOptions)
.subscribe(data =>
console.log(data);
);
proxy.conf.json
"/api*":
"target":"http://localhost:8080",
"secure":false,
"logLevel":"debug",
"changeOrigin": true
提前感谢您!
【问题讨论】:
您的proxy.conf.json
是否包含"changeOrigin": true
值?
是的,我添加了这个字段,但没有帮助。现在我的代理配置看起来像这样: "/api*": "target":"http://localhost:8080", "secure":false, "logLevel":"debug", "changeOrigin": true
这些端点是否对来自同一台机器的简单 curl(或其他一些客户端,如 postman)请求作出反应?
【参考方案1】:
@CrossOrigin
注解中不需要设置origins=*
,默认允许所有来源。
您尝试将注释放在方法级别?
【讨论】:
如您所见,注释也添加到类级别以及 origins 参数。是的,我也尝试在方法级别设置它,但没有成功。【参考方案2】:你可以试试这个:
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@EnableWebMvc
public class CorsConfig implements WebMvcConfigurer
@Override
public void addCorsMappings(CorsRegistry registry)
registry.addMapping("/**")
.allowedOrigins("https://localhost:4200")
.allowCredentials(true);
并确保您的 Angular 客户端发送他的凭据:
httpOptions =
withCredentials: true,
...
【讨论】:
关闭,我也找到了这种方法的解决方案,但我还需要添加allowedMethods("*")
和allowedHeaders("*")
【参考方案3】:
好吧,我解决了这个问题。
我不知道为什么,但是对于此类问题非常流行的解决方案 CORS Fitler 并没有改变任何代理配置,但是将 CorsConfigurationSource bean 和以下行添加到 configure
方法解决了问题。
SecurityConfig.java
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
//Controlling access
@Override
protected void configure(HttpSecurity http) throws Exception
http.authorizeRequests()
...
.and()
.cors()
@Bean
CorsConfigurationSource corsConfigurationSource()
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Collections.singletonList("*"));
configuration.setAllowedMethods(Collections.singletonList("*"));
configuration.setAllowedHeaders(Collections.singletonList("*"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
另外对我有用的第二个是添加以下类:
@Configuration
public class WebConfiguration implements WebMvcConfigurer
@Override
public void addCorsMappings(CorsRegistry registry)
registry
.addMapping("/**")
.allowedMethods("*")
.allowedHeaders("*")
.allowedOrigins("*")
.allowCredentials(false);
但在此解决方案中,将.and().cors()
行添加到安全配置中也是必要。
【讨论】:
【参考方案4】:这是 Angular 的一个非常烦人的配置。仅仅允许交叉起源是不够的。您还需要允许方法和一些标头。这个配置帮助了我:
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer
@Value("$angular")
private String angularOrigin;
@Bean
public WebMvcConfigurer corsConfigurer()
return new WebMvcConfigurer()
@Override
public void addCorsMappings(CorsRegistry registry)
registry
.addMapping("/**")
.allowedOrigins(angularOrigin)
.allowedHeaders("Authorization", "Cache-Control", "Content-Type", "Accept", "X-Requested-With", "Access-Control-Allow-Origin", "Access-Control-Allow-Headers", "Origin")
.exposedHeaders("Access-Control-Expose-Headers", "Authorization", "Cache-Control", "Content-Type", "Access-Control-Allow-Origin", "Access-Control-Allow-Headers", "Origin")
.allowedMethods("PUT","GET","POST","DELETE","OPTIONS");
;
还要注意应该允许一个 OPTION HTTP 方法。
【讨论】:
以上是关于Java Spring 控制器拒绝除 GET 之外的所有请求的主要内容,如果未能解决你的问题,请参考以下文章
Postgres:除 phpPgAdmin 之外的所有权限都被拒绝