问题:
CORS正在处理方法参数中没有@AuthenticatedPrincipal
的GET请求。
我正在使用
由于某种原因,我每次都会遇到此错误,我正在发出方法参数中带有@AuthenticatedPrincipal
的POST,PUT或不安全请求,但它适用于GET请求:
我已经使用Spring Boot阅读了有关CORS设置的所有可能的Stackoverflow问题,并像这样配置了我的CORS,但无济于事:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and()
.csrf().disable()
// .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
// .and()
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.antMatchers( "/courses", "/testing/*").permitAll()
.anyRequest().authenticated().and()
.oauth2Login().and()
.oauth2ResourceServer().jwt();
http.headers().frameOptions().disable();
}
// @Bean
// CorsConfigurationSource corsConfigurationSource() {
// CorsConfiguration configuration = new CorsConfiguration();
// configuration.setAllowedOrigins(Arrays.asList("*"));
// configuration.setAllowedMethods(Arrays.asList("POST", "GET", "PUT", "OPTIONS", "HEAD", "DELETE"));
// configuration.setAllowedHeaders(Arrays.asList("Content-Type"));
// configuration.setExposedHeaders(Arrays.asList("Authorization", "Link", "X-Total-Count", "Access-Control-Allow-Headers"));
// configuration.setAllowCredentials(true);
// UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
// source.registerCorsConfiguration("/**", configuration);
// return source;
// }
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration().applyPermitDefaultValues();
configuration.setAllowedOrigins(ImmutableList.of("*"));
configuration.setAllowedMethods(ImmutableList.of("OPTIONS", "HEAD", "GET", "POST", "PUT", "DELETE", "PATCH"));
// setAllowCredentials(true) is important, otherwise:
// The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the
// request's credentials mode is 'include'.
configuration.setAllowCredentials(true);
// setAllowedHeaders is important! Without it, OPTIONS preflight request
// will fail with 403 Invalid CORS request
configuration.setAllowedHeaders(ImmutableList.of("Authorization", "Cache-Control", "Content-Type"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
我的控制器
@CrossOrigin
@RestController
@RequestMapping(EndPoints.TEST_PATH)
public class TestController {
private final TestService tService;
@Autowired
public TestController(TestService tService) {
this.tService = tService;
}
@PostMapping(path="/create")
public ResponseEntity<String> addNewTest(@Valid @NonNull @RequestBody TestDTO data,
@AuthenticationPrincipal Jwt principal){
tokenUserEmail = token.getClaimAsString("sub");
tokenUid = token.getClaimAsString("uid");
tokenFullName = token.getClaimAsString("firstName") + " "
+ token.getClaimAsString("lastName");
TestEntity testEntity = new TestEntity();
testEntity.setName(tokenFullName);
testEntity.setGrade(data.grade);
testEntity.setNumber(data.number);
tService.addNewTest(testEntity);
}
}
我已经用尽了每个可能的Stackoverflow问题,创建了WebMvcConfigurerAdapter()
,设置和取消设置了@CrossOrigin
。在这一点上,我不知道我还能做什么...任何人都知道我该如何解决??
答案 0 :(得分:-1)
在CORS浏览器中,始终将简单的跨域请求(例如GET请求)发送到服务器。但是浏览器会检查服务器的响应标头(Access-Control-Allow-Origin),服务器是否允许跨域请求。这就是您的 GET 请求访问服务器的原因。但是 POST,PUT,DELETE 浏览器之类的非简单请求无法使请求进入服务器。而是,浏览器将预检请求发送到服务器,以检查是否允许跨域请求。如果来自服务器的响应包含支持跨域请求的标头,则只有浏览器才会执行实际的请求。此飞行前请求是作为 OPTIONS 请求发送的。这就是为什么您的错误说对预检请求的响应没有通过的原因。 启用Spring安全性后,Spring Security会针对未经身份验证的用户阻止所有预检请求。要允许通过预检请求,我们必须在安全配置中进行配置。
在csrf()之后删除disable()。然后在方法顶部添加 @CrossOrigin 批注。您也可以在注解中提及域。 @CrossOrigin(“ http:// localhost:3000”)
这是您唯一要做的事情。
答案 1 :(得分:-1)
预检请求是浏览器在实际请求之前发送的一个小请求。它包含以下信息:使用哪种HTTP方法,以及是否存在任何自定义的 HTTP标头(例如Access-Control-Allow-Methods
)。
执行POST
操作时,有2个步骤。第一个请求是OPTIONS
,因此是 preflight 请求。完成 preflight 后,您的浏览器就会知道允许或拒绝哪些请求类型。
在您的情况下,问题在于,当后端需要1个呼叫时,您正在发送2个(预检+实际请求)。
要解决此问题,您必须告诉您的后端在OPTIONS
请求到达时做出响应,并确定。
免责声明::我没有尝试使用您配置 cors (CorsConfigurationSource
)的方式进行尝试。但是,让我用一个简单的滤豆展示它
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
final HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Allow-Headers", ""Authorization, Cache-Control, Content-Type"");
response.setHeader("Access-Control-Max-Age", "3600");
//SEND OK or validate
if ("OPTIONS".equalsIgnoreCase(((HttpServletRequest) req).getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
chain.doFilter(req, res);
}
}
@Override
public void destroy() {
//
}
@Override
public void init(FilterConfig config) throws ServletException {
//
}
}