Spring Boot 3.0+下Spring Security中CORS导致POST请求失败的解决方法
Spring Boot 3.0+ 中Spring Security认证POST请求CORS问题求助
在Spring Boot 3.0+版本中,Spring Security的认证功能出现异常:所有POST请求无法正常执行,报错如下:
从源'http://localhost:3000'访问'http://localhost:9090/api/rest/users/auth'的XMLHttpRequest已被CORS策略阻止:预检请求的响应未通过访问控制检查:请求的资源上不存在'Access-Control-Allow-Origin'头。
但GET请求可正常工作,无此错误。适用于Spring Boot 3.0以下版本的CORS解决方案均无效。当前采用基于JWT Token、实现WebMvcConfigurer的REST配置,已尝试在前端请求和后端响应中添加所有推荐的请求头,但均无效果,推测问题出在该版本的Spring机制上,寻求有相同问题解决经验的开发者提供帮助。
相关代码
后端Java代码
@Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE, PATCH"); response.setHeader("Access-Control-Max-Age", "3600"); response.setHeader("Access-Control-Allow-Headers", "Accept-Encoding, origin, content-type, accept, token, x-auth-token, Access-Control-Allow-Origin, " + "Access-Control-Allow-Methods, Access-Control-Max-Age, Access-Control-Allow-Headers, " + "Content-Language, Content-Length, Keep-Alive, Authorization"); @RestController @RequestMapping("/users") @Slf4j @SecurityRequirement(name = "Bearer Authentication") @CrossOrigin(origins = "http://localhost:3000", allowedHeaders = "*") //localhost:9090/api/rest/users public class UserController extends GenericController<User, UserDTO> { private final CustomUserDetailsService customUserDetailsService; private final JWTTokenUtil jwtTokenUtil; private final UserService userService; public UserController(UserService userService, CustomUserDetailsService customUserDetailsService, JWTTokenUtil jwtTokenUtil) { super(userService); this.customUserDetailsService = customUserDetailsService; this.jwtTokenUtil = jwtTokenUtil; this.userService = userService; } @PostMapping("/auth") public ResponseEntity<?> auth(@RequestBody LoginDTO loginDTO) { Map<String, Object> response = new HashMap<>(); log.info("LoginDTO: {}", loginDTO); UserDetails foundUser = customUserDetailsService.loadUserByUsername(loginDTO.getLogin()); log.info("foundUser, {}", foundUser); if (!userService.checkPassword(loginDTO.getPassword(), foundUser)) { return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Ошибка авторизации!\nНеверный пароль"); } String token = jwtTokenUtil.generateToken(foundUser); response.put("token", token); response.put("username", foundUser.getUsername()); response.put("authorities", foundUser.getAuthorities()); return ResponseEntity.ok().body(response); } } @Configuration @EnableWebSecurity public class WebSecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http // by default uses a Bean by the name of corsConfigurationSource .cors(withDefaults()) ... return http.build(); } @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; } }
前端JavaScript代码
import {useAuthUserAppStore} from "@/store/app"; import LoginDTO from "@/models/LoginDTO"; class AuthService { login(loginDTOUser: LoginDTO) { const user = { login: loginDTOUser.login, password: loginDTOUser.password } const serializedUser = JSON.stringify(user); return http .post('/users/auth', serializedUser) .then(response => { if (response.data.accessToken) { useAuthUserAppStore().changeAuthUser(JSON.stringify(response.data)) console.log(useAuthUserAppStore().authUser) } return response.data; }); } }
内容的提问来源于stack exchange,提问作者евгений малков
相关产品推荐
相关产品推荐

