You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,提问作者евгений малков

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 01:55:35