在运行时将 CORS 映射动态添加到 Rest Controller
Posted
技术标签:
【中文标题】在运行时将 CORS 映射动态添加到 Rest Controller【英文标题】:Dynamically add CORS Mappings to Rest Controller at runtime 【发布时间】:2018-05-19 01:42:52 【问题描述】:你好!我是 Spring Boot 的初学者。我有一个使用 Rest Controller 的简单 Java Spring Boot 应用程序。一些控制器的端点暴露给 CORS 请求。我发现可以通过在方法上方添加 @CrossOrigin(origins ="..") 注释来允许 CORS 请求。 我的问题是我目前不知道所有的起源,并且必须稍后在我的 Spring Boot 应用程序运行时添加其中一些。 是否有一种方法可以手动将新的源地址添加到我的 Rest Controller 的某些端点?例如。在我的休息控制器中有一个端点,允许特定用户(例如管理员)将新的 cors-origins 添加到休息端点?如果是:请举一个简单的例子。
【问题讨论】:
您是否考虑过使用过滤器将这种横切关注点外部化? 问题解决了吗?如果有,请您回答一下好吗? 【参考方案1】:以下内容在 Spring 2.4 中为我工作:
import java.util.Arrays;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
@Configuration
public class CorsConfig
@Bean
public CorsFilter corsFilter()
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
final CorsConfiguration corsConfiguration = new CorsConfiguration();
final String corsAllowedOrigins = System.getenv("CORS_ALLOWED_ORIGINS");
corsConfiguration.setAllowCredentials(true);
corsConfiguration.setAllowedOrigins(Arrays.asList(corsAllowedOrigins.split(",")));
corsConfiguration.setAllowedMethods(Arrays.asList(CorsConfiguration.ALL));
corsConfiguration.setAllowedHeaders(Arrays.asList(CorsConfiguration.ALL));
source.registerCorsConfiguration("/**", corsConfiguration);
return new CorsFilter(source);
【讨论】:
【参考方案2】:我认为这可以通过实现您自己的org.springframework.web.cors.CorsProcessor
来实现。查看org.springframework.web.filter.CorsFilter
的实现,可以通过方法public void setCorsProcessor(CorsProcessor processor)
使用您的自定义CorsProcessor
进行配置。
然后我会建议实现您自己的 CorsProcessor
并在方法 process
中处理您的自定义规则。
或者另一种选择是在 Spring Security Config 中设置自己的 CorsConfigurationSource
。例如
@Override
protected void configure(HttpSecurity http) throws Exception
http.cors().configurationSource(new CustomConfigSource());
CorsConfigurationSource
提供了一种方法 CorsConfiguration getCorsConfiguration(HttpServletRequest request);
,您可以在其中处理特定的 CORS 处理。
【讨论】:
感谢您的回答。不幸的是,我有点困惑。我应该把自己的 CorsProcessor 放在哪里,我应该如何调用 getCorsConfiguration(HttpServletRequest req) 方法?我的 Rest Controller 中的任何地方都没有 HttpServletRequest 类型的参数。 ...如您所见,我是一个真正的初学者 我建议采用我提供的第二个选项。在 Spring Security Config 中将您自己的ConfigurationSource
添加到您的 cors 配置中。然后框架将为每个请求调用方法getCorsConfiguration(HttpServletRequest request);
【参考方案3】:
您可以通过res.addHeader("Access-Control-Allow-Origin","what you want here like http/.....");
直接将其添加到HttpServletResponse res中
@RequestMapping(value="/getbot/id",
method = RequestMethod.POST,
headers="Accept=application/json")
@ResponseBody public String getbot(HttpServletResponse res)
res.addHeader("Access-Control-Allow-Origin","*");
...
我试过用springboot没有办法做到这一点,因为默认的cors处理程序会覆盖你的标题,我没有找到阻止它的方法 我认为我们需要为我们无法动态执行的 springboot 编写 servlet
【讨论】:
【参考方案4】:@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException
response.addHeader("Access-Control-Allow-Origin", "*");
if (request.getHeader("Access-Control-Request-Method") != null && "OPTIONS".equals(request.getMethod()))
LOG.trace("Sending Header....");
// CORS "pre-flight" request
response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
response.addHeader("Access-Control-Allow-Headers", "Content-Type");
response.addHeader("Access-Control-Max-Age", "1");
filterChain.doFilter(request, response);
请使用过滤器cros_filter
【讨论】:
以上是关于在运行时将 CORS 映射动态添加到 Rest Controller的主要内容,如果未能解决你的问题,请参考以下文章
Angular 2 + CORS + 带有 Spring Security 的 Spring Boot Rest Controller
django-cors-headers 不适用于 DRF(Django Rest 框架)
无法为JAX-B生成架构,仅在CORS调用REST服务期间发生