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();
}
}