2

在使用安全管理器部署在 tomcat 中的 webapp 中,这有效:

URL url = servletContext.getResource("/WEB-INF/internal/tika/tika-app-1.2.jar");
// test to see if the content can be read
String test = IOUtils.toString(url);

Tomcat 使用 jndi 作为内部 URL。根据有关安全管理器的 tomcat 文档(此处链接),war 文件中的资源被授予隐式权限。

但是,这不起作用:

URL url = servletContext.getResource("/WEB-INF/internal/tika/tika-app-1.2.jar");
ClassLoader cl = new URLClassLoader(new URL[] { url }, this.getClass().getClassLoader());
// load a class from the jar
Class<TextExtractor> clz = (Class) cl.loadClass(" ... some class ...");
delegate = clz.newInstance();

我得到的例外是:

Caused by: java.security.AccessControlException: access denied (org.apache.naming.JndiPermission jndi:/localhost/my_webapp/WEB-INF/internal/tika/tika-app-1.2.jar)
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:374)
at java.security.AccessController.checkPermission(AccessController.java:546)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
at java.net.URLClassLoader$4.run(URLClassLoader.java:515)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.getPermissions(URLClassLoader.java:513)
at java.security.SecureClassLoader.getProtectionDomain(SecureClassLoader.java:235)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
at com.sample.myClass.afterPropertiesSet(TikaWrapper.java:38)

我想我的第一个问题是:为什么

如果我将它添加到 catalina.policy 文件中,那么它可以工作:

permission org.apache.naming.JndiPermission "jndi:/localhost/my_webapp/WEB-INF/internal/tika/tika-app-1.2.jar";

然而,客户不愿意或不能改变他的策略文件。

我的第二个问题是:知道该怎么做吗?我不能把 jar 放在 /WEB-INF/lib 下,否则我已经做了。我可以把它放在tomcat外面,并用基于file://的URL加载它,但我试图避免它。

4

1 回答 1

1

至于您的第一个问题,文档中有一个关于在安全管理器下运行时类加载的小注释,为了方便起见,在此处引用它:

在安全管理器下运行时,允许加载类的位置也取决于策略文件的内容。

因此,默认情况下,webapp 类加载器似乎只允许从 WEB-INF/lib 和 WEB-INF/classes 目录加载。在您的情况下,您似乎将 webapp 类加载器作为父级分配给您的自定义类加载器,因此后者与其父级相同,只能从 WEB-INF/lib 和 WEB-INF/classes 加载类.

至于怎么做,由于客户端不想或不能更改策略文件,请考虑尝试以编程方式更改策略。这里有一个很好的例子。但是,它只有在当前的权限集允许调用java.security.Permission.setPolicy() 方法时才有效,我敢打赌它不会,因为这会设置 JVM 系统范围的策略。

于 2013-01-17T22:07:13.767 回答