Java 如何使用自定义策略SPI

Java 如何使用自定义策略SPI,java,security,permissions,Java,Security,Permissions,我试图实现一个自定义的java.security.Permission类型,应该在运行时检查它(因此没有策略文件,而是在代码中)。此检查由java.security.Policy完成。我知道我应该为此实现自己的java.security.PolicySpi 我找不到任何关于如何初始化和使用PolicySpi的解释,或者有更好的方法吗?检查权限 在您的问题中,您表示希望使用java.security.Policy检查权限,但不使用spi.Policy文件 从中可以看到,PolicySpi对象具有4

我试图实现一个自定义的
java.security.Permission
类型,应该在运行时检查它(因此没有策略文件,而是在代码中)。此检查由
java.security.Policy
完成。我知道我应该为此实现自己的
java.security.PolicySpi

我找不到任何关于如何初始化和使用PolicySpi的解释,或者有更好的方法吗?

检查权限 在您的问题中,您表示希望使用
java.security.Policy
检查权限,但不使用
spi.Policy
文件

从中可以看到,PolicySpi对象具有4种方法:

  • 但是,您可能不需要PolicySpi,因为有更简单的解决方案来检查权限

    见:

    由于您尚未指定要授予的权限类型,因此我将假定它是关于对象的权限

    要检查文件的所有当前权限,请执行以下操作:

    public static void main(String[] args) {
    
        CodeSource source;
    
        try {
          source = new CodeSource(new URL("file:/c:/*"), (java.security.cert.Certificate[]) null);
    
          Policy policy = Policy.getPolicy();
          System.out.println(policy.getPermissions(source));
    
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    
    SecurityManager checkPermission()
    的一个很好的例子是

    要检查特定的,可以使用:

    FilePermission perm = new FilePermission("path/file", "read");
    AccessController.checkPermission(perm);
    
    授予权限 可以使用在运行时授予权限

    有关如何授予文件权限的其他示例,我建议您阅读以下内容:


    那会给你带来一段很长的路!祝你好运

    答案列出了使用
    PolicySpi
    (通常是自定义
    Policy
    实现)的替代方案。这个答案将给出一个简单的例子,说明如何实际使用
    PolicySpi
    实现来替代系统默认的
    策略

    package com.example;
    
    import java.security.NoSuchAlgorithmException;
    import java.security.Policy;
    
    public class Main {
    
        public static void main(String... args) throws NoSuchAlgorithmException {
            // the following assumes that the provider has been statically registered
            Policy.setPolicy(Policy.getInstance("TestPolicy", null));
            System.setSecurityManager(new SecurityManager());
    
            // test
            System.out.println(System.getProperty("user.home")); // should raise AccessControlException
        }
    
    }
    
  • 作者:JCA

  • 编写服务描述符生成的实际服务(本例中为
    PolicySpi
    实现)

    package com.example;
    
    import java.security.Permission;
    import java.security.Policy.Parameters;
    import java.security.PolicySpi;
    import java.security.ProtectionDomain;
    
    final class TestPolicySpi extends PolicySpi {
    
        TestPolicySpi(Parameters policyParams) {}
    
        @Override
        protected boolean engineImplies(ProtectionDomain domain, Permission permission) {
            // deny unconditionally
            return false;
        }
    
    }
    
  • 通过修改
    JAVA\u HOME/lib/security/JAVA.security
    中的
    security.provider.n
    属性静态注册提供程序,或通过
    JAVA.security.security.addProvider(provider)
    /
    JAVA.security.security.insertProviderAt(provider,int)
    以编程方式注册提供程序

  • 替换默认的
    策略

    package com.example;
    
    import java.security.NoSuchAlgorithmException;
    import java.security.Policy;
    
    public class Main {
    
        public static void main(String... args) throws NoSuchAlgorithmException {
            // the following assumes that the provider has been statically registered
            Policy.setPolicy(Policy.getInstance("TestPolicy", null));
            System.setSecurityManager(new SecurityManager());
    
            // test
            System.out.println(System.getProperty("user.home")); // should raise AccessControlException
        }
    
    }
    
  • 有更好的方法吗?

    当然还有一种不太复杂的方法,只要应用程序和策略之间的紧密耦合不会让您太烦恼:直接将
    policy
    子类化,并将实现的实例传递给
    policy.setPolicy(policy)

    进一步阅读:


    从Java 6开始,
    PolicySpi
    的默认实现是
    sun.security.provider.PolicySpiFile
    。您可以从
    PolicySpiFile
    中获得灵感:

    package sun.security.provider;
    
    import java.security.CodeSource;
    import java.security.Permission;
    import java.security.PermissionCollection;
    import java.security.Policy;
    import java.security.PolicySpi;
    import java.security.ProtectionDomain;
    import java.security.URIParameter;
    
    import java.net.MalformedURLException;
    
    /**
     * This class wraps the PolicyFile subclass implementation of Policy
     * inside a PolicySpi implementation that is available from the SUN provider
     * via the Policy.getInstance calls.
     *
     */
    public final class PolicySpiFile extends PolicySpi {
    
        private PolicyFile pf;
    
        public PolicySpiFile(Policy.Parameters params) {
    
            if (params == null) {
                pf = new PolicyFile();
            } else {
                if (!(params instanceof URIParameter)) {
                    throw new IllegalArgumentException
                            ("Unrecognized policy parameter: " + params);
                }
                URIParameter uriParam = (URIParameter)params;
                try {
                    pf = new PolicyFile(uriParam.getURI().toURL());
                } catch (MalformedURLException mue) {
                    throw new IllegalArgumentException("Invalid URIParameter", mue);
                }
            }
        }
    
        protected PermissionCollection engineGetPermissions(CodeSource codesource) {
            return pf.getPermissions(codesource);
        }
    
        protected PermissionCollection engineGetPermissions(ProtectionDomain d) {
            return pf.getPermissions(d);
        }
    
        protected boolean engineImplies(ProtectionDomain d, Permission p) {
            return pf.implies(d, p);
        }
    
        protected void engineRefresh() {
            pf.refresh();
        }
    }
    

    其思想是创建自定义权限(MyPermission)的运行时检查。由于在运行时检查可能会有所不同,因此我需要一个没有策略文件的实现。我已经使用了AccessController.checkPermission()。唯一的问题是我需要这个方法去一个提供运行时信息的接口,根据,
    每个Java运行时中只有一个AccessController实例。
    。这意味着默认上下文已经是当前
    运行时的上下文了。没错,我使用的是AccessController.checkPermission,它依次使用策略。策略应该执行特定的检查,例如,如果时间介于8:00和10:00之间,则允许权限,否则不允许权限。但这是可能的,特别是在“配置spi.policy文件”中,我现在知道如何开始使用它了。Thx.@OblongZebra:你的名声太糟糕了赏金:(你没有用它!很抱歉我反应太晚了。我要求stackoverflow允许你得到赏金,希望他们同意。
    
    package sun.security.provider;
    
    import java.security.CodeSource;
    import java.security.Permission;
    import java.security.PermissionCollection;
    import java.security.Policy;
    import java.security.PolicySpi;
    import java.security.ProtectionDomain;
    import java.security.URIParameter;
    
    import java.net.MalformedURLException;
    
    /**
     * This class wraps the PolicyFile subclass implementation of Policy
     * inside a PolicySpi implementation that is available from the SUN provider
     * via the Policy.getInstance calls.
     *
     */
    public final class PolicySpiFile extends PolicySpi {
    
        private PolicyFile pf;
    
        public PolicySpiFile(Policy.Parameters params) {
    
            if (params == null) {
                pf = new PolicyFile();
            } else {
                if (!(params instanceof URIParameter)) {
                    throw new IllegalArgumentException
                            ("Unrecognized policy parameter: " + params);
                }
                URIParameter uriParam = (URIParameter)params;
                try {
                    pf = new PolicyFile(uriParam.getURI().toURL());
                } catch (MalformedURLException mue) {
                    throw new IllegalArgumentException("Invalid URIParameter", mue);
                }
            }
        }
    
        protected PermissionCollection engineGetPermissions(CodeSource codesource) {
            return pf.getPermissions(codesource);
        }
    
        protected PermissionCollection engineGetPermissions(ProtectionDomain d) {
            return pf.getPermissions(d);
        }
    
        protected boolean engineImplies(ProtectionDomain d, Permission p) {
            return pf.implies(d, p);
        }
    
        protected void engineRefresh() {
            pf.refresh();
        }
    }