@CrossOrigin仅部分控制器方法生效,其余请求报net::ERR_FAILED CORS错误求助
现象描述
使用React作为前端、Spring作为后端服务,控制器类已添加@CrossOrigin注解,但仅POST类型的authenticate认证接口能正常访问,其余GET/POST接口均返回CORS错误。
错误信息
Access to fetch at 'http://localhost:9002/users/simpleUser/1,function%20()%20%7B%20[native%20code]%20%7D' from origin 'http://localhost:3000' 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. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
UserService.jsx:38GET http://localhost:9002/users/simpleUser/1,function%20()%20%7B%20[native%20code]%20%7D net::ERR_FAILED
后端控制器代码
@CrossOrigin @RestController @RequestMapping("/users") public class UserController { @Autowired private UserServiceImpl userService; @Autowired private JWTUtil jwtUtil; @Autowired private AuthenticationManager authenticationManager; @GetMapping("/simpleUser/{id}") public AppUser getUser(@PathVariable("id") Long userId) { return this.userService.getSimpleUser(userId); } @GetMapping("/all") public List<AppUser> getAllUsers() { return this.userService.getAllUsers(); } @PostMapping("/authenticate") public JwtResponse authenticate(@RequestBody JwtRequest jwtRequest) throws Exception { --some logic here-- }
前端React请求代码
async getUser(userId, token) { return await fetch(`${USER_ENDPOINTS.GET_USER}/${userId}`, { method: "GET", headers: { Authorization: `Bearer ${token}`, }, }).then(async (response) => { const userGot = await response.json(); console.log("user:" + userGot); return userGot; }); }
已尝试的无效方案
- 在单个接口方法上添加
@CrossOrigin(value="*")注解 - 在控制器类上添加
@CrossOrigin(maxAge = 3600, methods = {RequestMethod.POST, RequestMethod.GET})注解 - 在Security配置中简单添加
http.cors().and()配置
问题解决及原因
问题根源是Security配置中,cors配置被放置在认证规则(antMatchers)之后,导致跨域配置未被正确加载生效。
修复后的Security配置代码:
http.csrf() .disable() .authorizeRequests() .antMatchers("/users/save") .permitAll() .anyRequest() .authenticated() .and() .cors().and() .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS); http.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);
内容的提问来源于stack exchange,提问作者Jana Markovic

