gpt4 book ai didi

security - Tomcat 保护静态内容

转载 作者:行者123 更新时间:2023-11-28 21:46:33 25 4
gpt4 key购买 nike

我正在开发一项服务,其中包括向用户提供照片的“相册”功能。必须“允许”用户查看相册中的照片。因此,将直接链接发送给其他人不应允许查看照片。

照片存储在上下文之外的文件夹中。

我需要做的是在用户请求照片时执行一些检查,然后如果检查正常 - 提供文件。我想避免制作轮子,而只是让 tomcat 像通常为静态文件一样提供图像。您能就此提出一些建议吗?

最佳答案

好的,伙计们。

在努力解决这个问题之后,我想我终于找到了解决该问题的方法。首先,看起来这个问题实际上分解为两个独立的任务。其中之一是保护对某些资源的访问,第二个是从上下文之外的文件夹中提供资源。

第一个任务很简单,可以通过编写一个卡在“/”上的简单过滤器来解决。

第二个任务不那么琐碎,但幸运的是也可以解决。 Tomcat 使用 javax.naming.directory.DirContext 的实现来加载给定 Web 应用程序的所有资源,包括类文件。它还允许您提供此接口(interface)的自定义实现并在 context.xml 文件中对其进行配置。默认实现是 org.apache.naming.resources.FileDirContext。详情在这里:http://tomcat.apache.org/tomcat-6.0-doc/config/resources.html

我通过简单地扩展 FileDirContext 创建了自己的 DirContext 实现。幸运的是,只有一个方法必须被覆盖才能“连接”文件发现。该方法称为 file()。

我在这里发布我的测试代码。它远非完美,也没有考虑重命名文件等极端情况,但我认为在服务器的正常运行下不需要这些。

这段代码的基本思想是检查路径是否以“虚拟目录”前缀开头,如果是 - 在文件系统的其他地方搜索文件(我知道那里有一些重复的代码,但我希望你如果您想使用它,请不要那么懒惰地删除它:-)。自动调用 setVirtualName 和 setVirtualBase 以注入(inject)配置参数。

/**
* TODO: add javadocs
*
* @author Juriy Bura
*/
public class VirtualFolderDirContext extends FileDirContext {
private String virtualName;
private String realName;

private File virtualBase;
private String absoluteVirtualBase;


public VirtualFolderDirContext() {
super();
}

public VirtualFolderDirContext(Hashtable env) {
super(env);
}

public void setVirtualName(String path) {
virtualName = path;
}

public void setVirtualBase(String base) {
this.realName = base;
virtualBase = new File(realName);
try {
virtualBase = virtualBase.getCanonicalFile();
} catch (IOException e) {
// Ignore
}
this.absoluteVirtualBase = virtualBase.getAbsolutePath();
}

protected File file(String name) {
File file = null;
boolean virtualFile = name.startsWith(virtualName + "/");
if (virtualFile) {
file = new File(virtualBase, name.substring(virtualName.length()));
} else {
file = new File(base, name);
}

if (file.exists() && file.canRead()) {

if (allowLinking)
return file;

// Check that this file belongs to our root path
String canPath = null;
try {
canPath = file.getCanonicalPath();
} catch (IOException e) {
}
if (canPath == null)
return null;

// Check to see if going outside of the web application root
if (!canPath.startsWith(absoluteBase) && !canPath.startsWith(absoluteVirtualBase)) {
return null;
}

// Case sensitivity check
if (caseSensitive) {
String fileAbsPath = file.getAbsolutePath();
if (fileAbsPath.endsWith("."))
fileAbsPath = fileAbsPath + "/";
String absPath = normalize(fileAbsPath);
if (canPath != null)
canPath = normalize(canPath);
if (virtualFile) {
if ((absoluteVirtualBase.length() < absPath.length())
&& (absoluteVirtualBase.length() < canPath.length())) {
absPath = absPath.substring(absoluteVirtualBase.length() + 1);
if ((canPath == null) || (absPath == null))
return null;
if (absPath.equals(""))
absPath = "/";
canPath = canPath.substring(absoluteVirtualBase.length() + 1);
if (canPath.equals(""))
canPath = "/";
if (!canPath.equals(absPath))
return null;
}
} else {
if ((absoluteBase.length() < absPath.length())
&& (absoluteBase.length() < canPath.length())) {
absPath = absPath.substring(absoluteBase.length() + 1);
if ((canPath == null) || (absPath == null))
return null;
if (absPath.equals(""))
absPath = "/";
canPath = canPath.substring(absoluteBase.length() + 1);
if (canPath.equals(""))
canPath = "/";
if (!canPath.equals(absPath))
return null;
}
}
}

} else {
return null;
}
return file;

}
}

在您拥有此类之后,您必须将其打包并将该 jar 放入 Tomcat lib 文件夹中。由于显而易见的原因,它不能与 war 文件一起使用。在您的 context.xml 中,您应该添加如下配置行:

<?xml version="1.0" encoding="UTF-8"?>
<Context antiResourceLocking="true" antiJARLocking="true">

<Resources
className="com.juriy.tomcat.virtualdir.VirtualFolderDirContext"
virtualName="/upload"
virtualBase="c:/temp/up">
</Resources>
...
...

现在,任何时候用户请求/upload/都会被解析为 c:\temp。使用这种技术,您几乎可以从任何位置加载资源:http、共享文件夹、数据库,甚至版本控制系统。所以这很酷。

附言我花了一整天的时间让这一切一起工作所以如果你喜欢这个答案,请不要犹豫给我投票:-))

干杯

陪审团

关于security - Tomcat 保护静态内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2957986/

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