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

Spring Boot 2.7.10中@CrossOrigin未限制非指定源请求问题排查

问题:@CrossOrigin注解未限制非指定源的后端调用请求

我基于JDK 8与Spring Boot 2.7.10实现了两个Spring Boot应用,其中一个应用通过REST调用请求另一个应用。在被调用的应用中,我使用@CrossOrigin注解配置了CORS,指定允许的源为localhost:8085。

我将调用方应用部署在8080以外的其他端口,再次调用该带有@CrossOrigin注解的资源,理论上该资源应仅接受指定源的请求,但实际它也接受了其他源的请求。请问我是否遗漏了什么配置?@CrossOrigin并未限制不在源列表中的其他源发起的请求。

客户端代码

package com.example.CORSExampleClient.CORSClient;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class CORSClient {

    @Autowired
    private RestTemplate restTemplate;
    
    @GetMapping("callClient")
    public void callClient() {
        String response=restTemplate.getForObject("http://localhost:9000/getOrigin",String.class);
        System.out.println("Response "+response);
    }
}

带CORS限制的被调用方资源代码

package com.example.CORSExample;

import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@CrossOrigin(origins = "http://localhost:8085")
@RestController
public class CORSController {

    @GetMapping("getOrigin")
    public String getOrigin(@RequestParam(required = false, defaultValue = "World") String name){
        return "Hello "+name;
    }
}

被调用方主类代码

package com.example.CORSExample;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class CorsExampleApplication {

    public static void main(String[] args) {
        SpringApplication.run(CorsExampleApplication.class, args);
    }
}

解答

这不是配置遗漏,而是对@CrossOrigin的作用范围理解有误:

  • @CrossOrigin是用来限制浏览器端发起的跨域请求的,它是浏览器同源策略安全机制的一部分,只有请求来自浏览器时,浏览器才会检查CORS响应头并拦截不符合规则的请求。
  • 你用RestTemplate做的是后端服务之间的直接调用,这类请求不会经过浏览器,因此不会触发CORS检查,@CrossOrigin的配置对这类请求完全不起作用。

如果要限制后端服务之间的调用,需要用其他方式:

  • 借助Spring Security添加请求鉴权,比如基于API密钥、OAuth2等方式验证调用方身份。
  • 自定义拦截器或过滤器,检查请求头中的Origin字段(若调用方会携带),或检查请求来源IP、自定义请求头,不符合规则则直接拒绝请求。

以下是自定义过滤器的示例:

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class OriginFilter implements Filter {
    private static final String ALLOWED_ORIGIN = "http://localhost:8085";

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;

        String origin = req.getHeader("Origin");
        if (origin != null && !origin.equals(ALLOWED_ORIGIN)) {
            res.setStatus(HttpServletResponse.SC_FORBIDDEN);
            return;
        }
        chain.doFilter(request, response);
    }
}

在配置类中注册该过滤器:

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FilterConfig {
    @Bean
    public FilterRegistrationBean<OriginFilter> originFilter() {
        FilterRegistrationBean<OriginFilter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(new OriginFilter());
        registrationBean.addUrlPatterns("/getOrigin"); // 指定要拦截的接口
        return registrationBean;
    }
}

通过这种方式,就能限制只有指定源的请求(包括后端调用和浏览器请求)才能访问目标接口。


内容的提问来源于stack exchange,提问作者Darshana

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 01:27:04