java – 如何说服spring 4.2将OPTIONS请求传递给控制器

前端之家收集整理的这篇文章主要介绍了java – 如何说服spring 4.2将OPTIONS请求传递给控制器前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

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

    

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

    @RequestMapping(value="/some/collections",method=RequestMethod.OPTIONS)
    public void collectionOptions(
            HttpServletRequest req,HttpServletResponse res) {
        List

我们还有一个拦截器,它对CORS pre-flight进行基本检查,以查看原点是否可能具有任何权限.

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

    OPTIONS /api/collections?userId=122

如果您具有管理权限,或者您实际上是具有ID 122的用户,则可能被允许.此外,我们还有API密钥

    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让控制器处理OPTIONS请求的一些方法,无论预检请求处理程序是什么.

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

  AbstractHandlerMapping.getHandler(HSR request)

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

——–编辑————-

HTTP标准说明了以下关于OPTIONS方法内容

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

认为beyong只是CORS,我认为拦截CORS选项调用虽然相应的方法映射到控制器上是不正确的方法.是的,CORS是你可以用OPTIONS调用做的一件事.但它绝不是唯一的一个.

如果没有映射,并且如果使用不同的请求方法和@CrossOrigin注释映射处理程序方法,我希望触发内置CORS支持的假设会很好,但我不认为任何请求原始标头集应该只自动转到CORS处理程序.

最佳答案
我只是说服Spring 4.3通过添加自定义处理程序映射将CORS预检传递给我的控制器:

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请求分配给您的控制器 – 也就是说,在dispatcherServlet中将dispatchOptionsRequest设置为true,就像它在this question中所说的那样.

为什么工作

Sébastien的above answer建议使用您自己的CorsProcessor.据我所知,这仍然不会使用您的控制器作为处理程序;它只会将不同的CorsProcessor传递给自己的CORS处理程序.

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

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

它在这里做的是使用PreFlightHandler而不是控制器重建执行链.这不是我们想要的,所以我们可以覆盖它以返回输入链.

猜你在找的Spring相关文章