gpt4 book ai didi

java - 我如何说服 spring 4.2 将 OPTIONS 请求传递给 Controller

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:16:32 24 4
gpt4 key购买 nike

我们在 Controller 上使用带有 @RestController 注释的 spring mvc,并且我们在 Controller 中处理授权。我们使用相同的代码来设置允许的方法以响应 CORS 飞行前请求。为实现这一目标,我们有:

    <init-param>
<param-name>dispatchOptionsRequest</param-name>
<param-value>true</param-value>
</init-param>

在调度器 servlet 的配置中,然后我们有:

    @RequestMapping(value="/some/collections", method=RequestMethod.OPTIONS)
public void collectionOptions(
HttpServletRequest req,
HttpServletResponse res) {
List<RequestMethod> methods = new ArrayList<>();
// check actual permissions, add the appropriate methods
CORS.setAllowedMethodHeaders(res,methods);
}

我们还有一个拦截器,可以在飞行前对 CORS 进行基本检查,以查看源是否可能拥有任何权限。

我们这样做主要是因为某些请求的权限实际上取决于@RequestParams,即:

    OPTIONS /api/collections?userId=122

如果您具有管理权限或者您实际上是 ID 为 122 的用户,则可能会被允许。另外,我们有 API key ,所以

    OPTIONS /api/collections?userId=122&apiKey=ABC

对于一个来源可能没问题,但对于另一个来源则不行。

这工作正常,但 spring 4.2 现在决定是否处理 OPTIONS 请求,通过调用:

    CorsUtils.isCorsRequest(request);

在AbstractHandlerMapping中然后返回

        HandlerInterceptor[] interceptors = chain.getInterceptors();
chain = new HandlerExecutionChain(new PreFlightHandler(config), interceptors);

而不是 HandlerMethod ...

我们需要的是某种方式告诉 spring 让 Controller 处理 OPTIONS 请求,无论存在什么预检请求处理程序。

我们似乎无法找到让内置 CORS 处理安静或在某处配置一些子类以允许我们绕过新添加代码的地方:

  AbstractHandlerMapping.getHandler(HSR request)

这有可能吗?在我主动启用它(通过 WebMvcConfigurerAdapter 或通过那些 @CrossOrigin 注释)之前,让这样的功能保持安静不是很好吗?

--------编辑------------

HTTP 标准对 OPTIONS 方法的描述如下:

OPTIONS 方法表示请求有关请求 URI 标识的请求/响应链上可用的通信选项的信息。此方法允许客户端确定与资源关联的选项和/或要求,或服务器的功能,而不暗示资源操作或启动资源检索。

考虑到 CORS,我认为拦截 CORS 选项调用虽然相应的方法映射到 Controller 上不是正确的方法。是的,CORS 是您可以通过 OPTIONS 调用做的一件事。但它绝不是唯一的。

如果没有任何映射,并且如果处理程序方法使用不同的请求方法和@CrossOrigin 注释进行映射,我希望触发内置 CORS 支持的假设就可以了,但我认为任何设置了原始 header 的请求都不应自动仅转到 CORS 处理程序。

最佳答案

我刚刚说服 Spring 4.3 通过添加自定义处理程序映射将 CORS 预检传递给我的 Controller :

public class CorsNoopHandlerMapping extends RequestMappingHandlerMapping {

public CorsNoopHandlerMapping() {
setOrder(0); // Make it override the default handler mapping.
}

@Override
protected HandlerExecutionChain getCorsHandlerExecutionChain(HttpServletRequest request,
HandlerExecutionChain chain, CorsConfiguration config) {
return chain; // Return the same chain it uses for everything else.
}
}

注意:您仍然需要告诉 Spring 将 OPTIONS 请求分派(dispatch)到您的 Controller 开始 - 也就是说,在 dispatcherServlet 中将 dispatchOptionsRequest 设置为 true 就像它说的那样在 this question .

为什么有效

塞巴斯蒂安的 above answer建议使用您自己的 CorsProcessor。据我所知,这仍然不会使用您的 Controller 作为处理程序;它只会将不同的 CorsProcessor 传递给它自己的 CORS 处理程序。

默认情况下,方法 AbstractHandlerMapping#getCorsHandlerExecutionChain 会在检测到预检时抛出您的 Controller 。它不是使用您的 Controller 作为处理程序,而是实例化一个新的 PreFlightHandler 并使用它。参见 Spring source code .这是有问题的行:

chain = new HandlerExecutionChain(new PreFlightHandler(config), interceptors);

它在这里所做的是使用 PreFlightHandler 而不是您的 Controller 重建执行链。这不是我们想要的,因此我们可以覆盖它以返回输入链。

关于java - 我如何说服 spring 4.2 将 OPTIONS 请求传递给 Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35982266/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com