Spring Boot接口执行成功后返回403错误排查求助
Spring Security中/api/chat接口执行正常但返回403的问题
开发了/api/chat接口,调用时会向OpenAI API发起请求(API密钥有效且已付费)。测试流程如下:
- 先调用
/auth/login接口获取有效的JWT登录令牌,该令牌在其他所有接口中均能正常工作 - 将令牌填入
/api/chat请求的Authorization头中,通过Postman发送请求
问题现象
发起/api/chat请求后,Postman耗时约1.5-2秒处理:
- 前1秒内,IntelliJ运行控制台记录请求发起的正确日志
- 剩余时间打印OpenAI API返回的预期响应,日志显示执行完全正常
但Postman及前端网站最终收到的是403响应,而非200 OK,导致无法提取响应内容,网站判定请求完全失败。
临时方案(不可行)
在SecurityConfig中将/api/chat设为公开接口(加入.permitAll()列表),此时接口执行流程不变,能正常返回200 OK,但会导致付费接口被公开访问,存在安全风险。
已排查内容
- 验证JWT认证逻辑无问题
- 确认令牌有效性
- 排查CORS和CSRF问题,均无结果
推测问题出在Spring Security层面,因为仅开放接口权限就能正常返回。
本人是Spring新手,恳请指点。API密钥已配置在环境变量中,日志仅打印预期响应,无错误信息。
相关代码
SecurityConfig 配置
@Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http.csrf() .disable() .authorizeHttpRequests(authorize -> authorize .requestMatchers("/auth/**", "/", "/index.html", "/manifest.json", "/static/**", "/*.js", "/*.jsx", "/*.css", "/home", "/log-in", "/sign-up") .permitAll() .requestMatchers("/auth/signup", "/auth/login").anonymous() .anyRequest() .authenticated() ) .sessionManagement(session -> session .sessionCreationPolicy(SessionCreationPolicy.STATELESS) ) .authenticationProvider(authenticationProvider) .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); return http.build(); }
Controller 代码
@PostMapping public Mono<ResponseEntity<String>> getChatCompletion(@RequestBody ChatRequest chatRequest, @RequestHeader HttpHeaders headers) { return openAiService.getChatCompletion(chatRequest.getInput()) .map(response -> { logger.info("Response: {}", response); // Logging response return ResponseEntity.ok(response); }) .defaultIfEmpty(ResponseEntity.noContent().build()); } public static class ChatRequest { private String input; public String getInput() { return input; } public void setInput(String input) { this.input = input; } }
Service 代码
public Mono<String> getChatCompletion(String userInput) { String requestBody = String.format("""{ "model": "gpt-3.5-turbo", "messages": [ { "role": "system", "content": "MY CONTENT" }, { "role": "user", "content": "%s" } ], "temperature": 1, "max_tokens": 256, "top_p": 1, "frequency_penalty": 0, "presence_penalty": 0 }""", userInput); logger.info("Sending request to OpenAI with body: {}", requestBody); return this.webClient.post() .uri("/chat/completions") .header("Content-Type", "application/json") .header("Authorization", "Bearer " + openaiApiKey) .bodyValue(requestBody) .retrieve() .bodyToMono(String.class) .doOnNext(response -> logger.info("Received response from OpenAI: {}", response)) .doOnError(WebClientResponseException.class, error -> { logger.error("Error response from OpenAI: {}", error.getResponseBodyAsString()); }) .doOnError(error -> logger.error("Error occurred: ", error)); }
Postman 请求示例
{ "input": "MY INPUT" }
内容的提问来源于stack exchange,提问作者vbsc
相关产品推荐
相关产品推荐

