我有一个使用各种第三方API的应用程序,其中一个第三方API在一个单独的线程中执行。
我希望一个特定的线程可以访问特定目录并限制该线程访问本地磁盘的其他目录。
这可以通过java安全管理器来实现吗?
答案 0 :(得分:3)
如果我理解正确,听起来你想要做的是限制你正在使用的第三方库之一的文件系统的访问权限。就Java SecurityManager而言,这个特定的第三方库在单独的线程中运行这一事实并不相关:Java安全策略根据代码的加载位置授予权限,是否已签名,或运行代码的用户,但不是基于运行代码的线程。
要限制特定库对文件系统的某些区域的访问,您需要一个策略文件,该文件授予您对所有其他代码的必要权限,以及对您要限制的库的有限权限。假设您运行的代码位于一组单独的jar文件中,并且您不想对任何其他代码施加任何限制,那么您的策略文件将如下所示:
grant codebase "file:/path/to/your-application.jar" {
permission java.security.AllPermission;
};
grant codebase "file:/path/to/trusted-library.jar" {
permission java.security.AllPermission;
};
grant codebase "file:/path/to/another-trusted-library.jar" {
permission java.security.AllPermission;
};
grant codebase "file:/path/to/restricted-library.jar" {
permission java.io.FilePermission "/path/to/particular/directory", "read,write";
// Any additional permissions this library needs
};
可能需要进行一些反复试验才能发现您需要授予受限制的库的其他特定权限才能使其正常运行。
如果您的要求确实是限制对特定线程的访问,那么您需要编写自定义SecurityManager并覆盖checkPermission方法,以便它们检查调用该方法的线程以确定是否应该使用该权限被授予。您需要向自定义SecurityManager添加方法,以允许您的应用程序代码注册应限制哪些线程,并且您需要确保受限代码无法调用这些其他方法,例如,通过创建和检查自定义权限。
编写自定义SecurityManagers通常比使用标准SecurityManager更具风险,因此如果采用这种方法,您将需要进行一些仔细的测试。
答案 1 :(得分:1)
假设您打算信任的库写得很好,您可以在策略文件中设置每个库的权限,并在线程内或其构造周围添加对java.security.AccessController.doPrivileged
的调用。通常免责声明严重写入可信代码将允许不受信任的代码利用其信任。
自从1998年发布的Java 2以来,“自定义”安全管理器通常是不必要的,但它似乎确实出现在很多民间记忆中。