12

如何在不使用策略文件的情况下以编程方式授予 RMI 应用AllPermissions程序

更新:

经过一番研究,我编写了这个自定义策略类并通过Policy.setPolicy(new MyPolicy()).

现在我收到以下错误:

无效权限:(java.io.FilePermission \C:\eclipse\plugins\org.eclipse.osgi_3.7.0.v20110613.jar 读取

class MyPolicy extends Policy {

    @Override
    public PermissionCollection getPermissions(CodeSource codesource) {
        return (new AllPermission()).newPermissionCollection();
    }

}
4

4 回答 4

13

根据@EJP的建议,我使用-Djava.security.debug=access并在策略文件中找到了所有需要的权限:

授予 { 权限 java.net.SocketPermission "*:1024-", "connect, resolve"; };

授予 { 权限 java.util.PropertyPermission "*", "read, write"; };

授予 { 权限 java.io.FilePermission "<>", "read"; };

但是因为我不想创建策略文件,所以我找到了一种通过扩展java.security.Policy类并在我的应用程序启动时使用设置策略以编程方式复制它的方法Policy.setPolicy(new MinimalPolicy());

public class MinimalPolicy extends Policy {

    private static PermissionCollection perms;

    public MinimalPolicy() {
        super();
        if (perms == null) {
            perms = new MyPermissionCollection();
            addPermissions();
        }
    }

    @Override
    public PermissionCollection getPermissions(CodeSource codesource) {
        return perms;
    }

    private void addPermissions() {
        SocketPermission socketPermission = new SocketPermission("*:1024-", "connect, resolve");
        PropertyPermission propertyPermission = new PropertyPermission("*", "read, write");
        FilePermission filePermission = new FilePermission("<<ALL FILES>>", "read");

        perms.add(socketPermission);
        perms.add(propertyPermission);
        perms.add(filePermission);
    }

}

class MyPermissionCollection extends PermissionCollection {

    private static final long serialVersionUID = 614300921365729272L;

    ArrayList<Permission> perms = new ArrayList<Permission>();

    public void add(Permission p) {
        perms.add(p);
    }

    public boolean implies(Permission p) {
        for (Iterator<Permission> i = perms.iterator(); i.hasNext();) {
            if (((Permission) i.next()).implies(p)) {
                return true;
            }
        }
        return false;
    }

    public Enumeration<Permission> elements() {
        return Collections.enumeration(perms);
    }

    public boolean isReadOnly() {
        return false;
    }

}
于 2012-08-01T13:39:52.917 回答
2

因为你的

新的 AllPermission()).newPermissionCollection()

被Java视为不可变的(为什么要向已经允许所有权限的集合添加权限?),并且因为Java会尝试向集合添加权限。这就是错误消息的来源 - Java 尝试将 java.io.FilePermission 添加到您的 AllPermission。

相反,请执行以下操作:

class MyPolicy extends Policy {
    @Override
    public PermissionCollection getPermissions(CodeSource codesource) {
        Permissions p = new Permissions();
        p.add(new PropertyPermission("java.class.path", "read"));
        p.add(new FilePermission("/home/.../classes/*", "read"));
        ... etc ...
        return p;
    }
}
于 2014-10-20T22:17:32.740 回答
1

不要安装 SecurityManager。仅当您使用代码库功能时才需要它,并且如果您需要适当的 .policy 文件,

于 2012-07-31T13:01:05.287 回答
1

简短的解决方案

将更新后的解决方案扩展到:

public class MyPolicy extends Policy
{
    @Override
    public PermissionCollection getPermissions(CodeSource codesource)
    {
        Permissions p = new Permissions();
        p.add(new AllPermission());
        return p;
    }
}

考虑一下,Policy.getPermissions()必须始终返回一个可变的PermissionCollection

返回: ...如果支持此操作,则返回的权限集必须是新的可变实例,并且必须支持异构权限类型...

该解决方案已经有效,因为它将 AllPermission 对象添加到 的每次调用中Policy.getPermissions(ProtectionDomain),即Policy.getPermissions(CodeSource).

清洁溶液

但是有一个更干净的解决方案,它不会跟踪任何不必要的其他权限,因为 AllPermissions 已经允许几乎所有内容。

public class MyPolicy extends Policy
{
    private static class AllPermissionsSingleton extends PermissionCollection
    {
        private static final long serialVersionUID = 1L;
        private static final Vector<Permission> ALL_PERMISSIONS_VECTOR = new Vector<Permission>(Arrays.asList(new AllPermission()));

        @Override
        public void add(Permission permission)
        {
        }

        @Override
        public boolean implies(Permission permission)
        {
            return true;
        }

        @Override
        public Enumeration<Permission> elements()
        {
            return ALL_PERMISSIONS_VECTOR.elements();
        }

        @Override
        public boolean isReadOnly()
        {
            return false;
        }
    }

    private static final AllPermissionsSingleton ALL_PERMISSIONS_SINGLETON = new AllPermissionsSingleton();

    @Override
    public PermissionCollection getPermissions(CodeSource codesource)
    {
        return ALL_PERMISSIONS_SINGLETON;
    }
}
于 2017-09-20T15:55:20.773 回答