Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 安全管理器与访问控制器_Java_Security - Fatal编程技术网

Java 安全管理器与访问控制器

Java 安全管理器与访问控制器,java,security,Java,Security,我试图阻止玩家的某些行为,但不是阻止我的游戏基础设施,为此我使用了一个安全管理器。看起来像这样 public class GameSecurityManager extends SecurityManager { @Override public void checkPackageAccess(String pkg) { super.checkPackageAccess(pkg); if (isPlayer()) { if (pkg.startsWith("ca.hilikus.jrob

我试图阻止玩家的某些行为,但不是阻止我的游戏基础设施,为此我使用了一个安全管理器。看起来像这样

public class GameSecurityManager extends SecurityManager {
@Override
public void checkPackageAccess(String pkg) {
 super.checkPackageAccess(pkg);
 if (isPlayer()) {
  if (pkg.startsWith("ca.hilikus.jrobocom")) {
   if (!"ca.hilikus.jrobocom.player".equals(pkg) && !"ca.hilikus.jrobocom.robot.api".equals(pkg)) {
        throw new SecurityException("No access to game packages");
   }}}
}
}
关于安全管理器的文档非常稀少,大部分都是90年代的。情况更糟。然而,我确实找到了它的状态

我们鼓励在应用程序代码中使用AccessController,而定制安全管理器(通过子类化)应该是最后的选择,并且应该非常小心地完成


你同意这个说法吗?有人能解释这是为什么吗?如果是这样的话,我将如何完成类似于我粘贴的示例代码的工作?我试图阻止反射、线程和基于上下文实例化一些对象(如上面的
isPlayer()
)。访问控制javadoc讨论的唯一一件事是特殊代码块中的特权操作,但它没有显示如何使用控制器来实际阻止操作

您不需要编写自己的SecurityManager或AccessController,您需要的是自定义。在您编写一个之后,您只需要启动SecurityManager并对您想要保护的每个方法进行安全检查!您可能需要执行私密操作以避免过多检查传播。:)

(为了未来用户的利益)

答案是您应该为应用程序提供一个安全策略。如果这是不可能控制的,那么你就是运气不好

在策略中,您将为“托管扩展”授予对某些合适子集的访问权限,其中“游戏包”将被授予所有权限。然后,为库创建权限,并授予对“托管扩展”的适当访问权

然后在您的API中,您将执行以下操作:


公共字符串someMethod(字符串someArg)
{
if(System.getSecurityManager()==null)
返回internalSomeMethod(someArg);
MyPermission required=新的MyPermission(“任何”);
AccessController.checkPermission(必需);
return AccessController.doPrivileged(新的PrivilegedAction()
{
公共字符串run()
{
返回内部方法(somArg);
}
} );
}

私有字符串someInternalMethod(字符串someArg){…}

因此,即使“托管扩展”只有“MyPermission”,游戏引擎也可以拥有所有权限并允许做任何它想做的事情,而“扩展”甚至不能读取系统属性。

引用本书“6.4.9
SecurityManager
AccessController
”一节:

回想一下本章前面的调用安全检查时,调用
checkPermission
和调用
SecurityManager
类中定义的其他
check
方法之间的区别。然后,选择取决于您是否依赖于任何Java 2之前的安全管理器类。现在您有了另一个选择:调用
SecurityManager
中定义的
checkPermission
方法或
AccessController
中定义的方法。这些方法在两个主要方面有所不同

首先,有时不存在已安装的
SecurityManager
,因此无法对其调用
check
checkPermission
方法。相比之下,
AccessController
中的静态方法总是可以调用的。回想一下调用
SecurityManager
的习惯用法:

SecurityManager sm = System.getSecurityManager();
if (sm != null)
    sm.checkPermission(permission);
但是你可以随时打电话

AccessController.checkPermission(permission);
因此,无论是否安装了系统范围的
SecurityManager
,如果要确保始终调用安全检查,则应调用
AccessController
。但是,请注意,一些现有应用程序测试是否安装了
SecurityManager
的实例。然后,根据此测试的结果(表示一个或其他安全状态),这些应用程序将采取不同的操作。为了实现这些应用程序的向后兼容性,调用
SecurityManager
更合适

第二个区别是调用
SecurityManager
不能保证特定的访问控制算法;可能有人扩展了它并安装了自定义安全管理器。相反,调用
AccessController
可以保证使用前面指定的完全访问控制算法。因此,如果不想将安全检查委托给自定义安全管理器,则应直接调用
AccessController
。否则,请调用
SecurityManager

另外,请注意,由于
SecurityManager
类定义了用于安全检查的通用接口,因此它不提供
AccessController
定义的特权机制。事实上,如果您在代码中使用特权机制,但后来调用
SecurityManager
执行安全检查,则如果您安装的安全管理器不是Java 2提供的安全管理器,并且未参考
AccessController
或其等效工具,则可能不会考虑特权状态

您可能想知道我们为什么提供这些选择。一种做事的方式还不够好吗?这些选择基于经验。需要在通用性和一致性之间进行平衡。从长远来看,我们希望不经常需要定制安全管理器,而且即使定义了它们,它们也将基于
AccessController
中的现有功能构建。特别是,它们将提供额外的功能,而不是促进不兼容的行为。然而,在一个必须强制执行截然不同的安全策略的特殊环境中,定制的安全管理器可能无法实现
AccessController.checkPermission(permission);