使用JRebel 6.0.0进行部署时,在Spring 4.1.2更新后找不到资源 [英] Resource Not Found after Spring 4.1.2 Update when deploy with JRebel 6.0.0

查看:146
本文介绍了使用JRebel 6.0.0进行部署时,在Spring 4.1.2更新后找不到资源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Spring 4.1.2(4.0.8和3.2.12)包含一个安全修正版 SPR- 12354 阻止 ResourceHttpRequestHandler < mvc:resources> 背后的东西)从中加载文件在资源文件夹之外。



另一方面:是 JRebel (我使用它的默认配置)。接下来,JRebel做了一些魔术来加载不是来自wtp文件夹的资源,而是直接形成源文件夹。



所以从Spring 3.2.11升级到3.2.12(以及4.0.7到4.0.8中的其他类似应用程序)Springs ResourceHttpRequestHandler 不再提供由JRebel维护的资源文件。而是传递404.原因是Spring将配置的资源文件夹的绝对文件路径与将要传递的文件的绝对文件路径进行比较。如果 ResourceHttpRequestHandler 认为该文件在配置的资源文件夹之外,则它假定用于选择该文件的URL是恶意的。因此 ResourceHttpRequestHandler 和找不到404资源的响应。



我希望JRebel可以配置为不维护js,png和css文件,但我不知道如何。这就是问题:如何配置JRebel,Spring MVC应用程序(v 4.0.8)仍然使用 ResourceHttpRequestHandler

(我希望在升级到Spring 4.1.2,4.0.8或3.2.12之后几乎每个JRebel用户都面临这个问题。)



(不要误会我的意思,这不是一个如何操纵Spring不要检查文件是否在配置资源文件夹之外的问题。我已经看过源代码了观察到的行为是Bug修复的作者所期望的行为。 - 这个问题是关于配置JRebel)

解决方案

问题已在JRebel中修复(我无法使用当前的JRebel 6.1.1重现它) - 我想它是固定的自6.0.2 (23rd 2014年12月)


修复了Spring ResourceHttpRequestHandler无法提供资源的问题在webroot之外。


(JRebel Changelog https://zeroturnaround.com/software/jrebel/download/changelog/6-x/






对于有兴趣的人如何解决它:



我只能猜测,因为它很奇怪。
Spring 4.1.6(即我用于测试的版本)具有类 org.springframework.web.servlet.resource.PathResourceResolver 具有方法 checkResource(资源资源,资源位置)

  protected boolean checkResource(Resource资源,资源位置)抛出IOException {
if(isResourceUnderLocation(resource,location)){
return true;
}
if(getAllowedLocations()!= null){
for(资源当前:getAllowedLocations()){
if(isResourceUnderLocation(resource,current)){
返回true;
}
}
}
返回false;
}

第一个如果 isResourceUnderLocation ... 是检查请求是否正在访问配置的资源文件夹之外的资源的方法

  isResourceUnderLocation(资源资源,资源位置){
...
resourcePath =((ServletContextResource)资源).getPath();
locationPath = StringUtils.cleanPath(((ServletContextResource)location).getPath());
...
if(!resourcePath.startsWith(locationPath)){
return false;
}
...
}

当我使用调试器检查发生了什么,当JRebel处于活动状态时,发生了一些奇怪的事情:当JVM命中行 if(isResourceUnderLocation(resource,location)){时,那么方法 isResourceUnderLocation 未被调用!



所以我得出的结论是JRebel做了一些字节码操作以防止检查(以及整个 isResourceUnderLocation 方法)被执行。


Spring 4.1.2 (4.0.8 and 3.2.12) contains a Security Bugfix SPR-12354 that prevents the ResourceHttpRequestHandler (the thing behind <mvc:resources>) to load files from outside the the resource folder.

On the other hand: is JRebel (I use it with its default configuration). And it seams that JRebel do some magic to load the resources not from the wtp folder but directly form the "source" folder.

So after upgrading from Spring 3.2.11 to 3.2.12 (and an other similar Application from 4.0.7 to 4.0.8) Springs ResourceHttpRequestHandler does not longer deliver the resource files that are "maintained" by JRebel. Instead is delivers a 404. The reason is that Spring compare the absolute file path of the configured resource folder with the absolute file path of the file that is going to be delivered. If the ResourceHttpRequestHandler perceived that the file is outside of configured resource folder, then it assume that the url that was used to select the file is malicious. Therefore the ResourceHttpRequestHandler and response with a 404 resource not found.

I expect that JRebel can been configured not to "maintain" js, png and css files, but I don't know how. And this is the question: How to configure JRebel that a Spring MVC Application (v 4.0.8) still deliver Resources with ResourceHttpRequestHandler?

(I expect that almost every JRebel User is facing this problem after upgrading to Spring 4.1.2, 4.0.8 or 3.2.12).

(don't get me wrong, this is NOT a question how to manipulate Spring not to check that the files are outside of the configures resource folder. I have had a look at the source code and the observed behaviour is the behaviour that is intended by the authors of the Bug fix. - This question is about configuring JRebel)

解决方案

The problem is fixed in JRebel (I can not reproduce it with the current JRebel 6.1.1) - I guess it is fixed since 6.0.2 (23rd December 2014)

Fixed an issue where Spring ResourceHttpRequestHandler could not serve resources outside of webroot.

(JRebel Changelog https://zeroturnaround.com/software/jrebel/download/changelog/6-x/)


For the one that are interested how they solved it:

I can only guess because it is strange. Spring 4.1.6 (that is the version I used for the test) has the class org.springframework.web.servlet.resource.PathResourceResolver has the method checkResource(Resource resource, Resource location):

protected boolean checkResource(Resource resource, Resource location) throws IOException {
    if (isResourceUnderLocation(resource, location)) {
        return true;
    }
    if (getAllowedLocations() != null) {
        for (Resource current : getAllowedLocations()) {
            if (isResourceUnderLocation(resource, current)) {
                return true;
            }
        }
    }
    return false;
}

The first if: isResourceUnderLocation... is the method that check whether or not the request is accessing a resource outside the configured resource folder

isResourceUnderLocation(Resource resource, Resource location) {
    ...
    resourcePath = ((ServletContextResource) resource).getPath();
    locationPath = StringUtils.cleanPath(((ServletContextResource) location).getPath());
    ...
    if (!resourcePath.startsWith(locationPath)) {
        return false;
    }
    ...
 }

When I use the debugger to check what is going on, while JRebel is active, then something strange happend: when the JVM hit the line if (isResourceUnderLocation(resource, location)) {, then the method isResourceUnderLocation gets not invoked!

So I came to the conclusion that JRebel does some bytecode manipulation to prevent that the check (and the whole isResourceUnderLocation method) gets executed.

这篇关于使用JRebel 6.0.0进行部署时,在Spring 4.1.2更新后找不到资源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆