Java SecurityManager AccessControlException-从网络共享运行

Java SecurityManager AccessControlException-从网络共享运行,java,securitymanager,javapolicy,Java,Securitymanager,Javapolicy,我有一个Java8应用程序,它通过Nashorn JavaScript脚本引擎评估用户提供的代码。为了防止恶意代码评估,我使用以下策略启用Java SecurityManager: grant codeBase "file:/-" { permission java.security.AllPermission; }; grant { permission java.net.SocketPermission "*", "accept,connect,resolve"; }; 这允许我的主

我有一个Java8应用程序,它通过Nashorn JavaScript脚本引擎评估用户提供的代码。为了防止恶意代码评估,我使用以下策略启用Java SecurityManager:

grant codeBase "file:/-" {
 permission java.security.AllPermission;
};

grant {
 permission java.net.SocketPermission "*", "accept,connect,resolve";
};
这允许我的主Java应用程序不受限制地运行,但任何JavaScript代码都仅限于通过第二个授权块授予的权限。我将我的应用程序打包到一个MyApp.jar文件中,一般来说,这样做很好,每次有人试图从我的脚本引擎中调用
java.lang.System.exit()
,等等,都会引发AccessControlException

现在来看问题-如果我将jar文件放在网络共享上(
\\global\fs\Technology\Tools\MyApp.jar
),那么我的应用程序无法加载,因为“AllPermission”授权块似乎与我的代码库不匹配。 有没有其他人遇到过这个问题并知道如何解决它?这只会发生在网络驱动器上,如果我将它放在其他地方,则不会发生

以下是调试输出-

java -Djava.security.manager -Djava.security.policy=mypolicy -Djava.security.debug=access -jar \\global\fs\Technology\Tools\MyApp.jar
这将导致以下错误消息:

access: access allowed ("java.io.FilePermission" "\\global\fs\Technology\Tools\MyApp.jar" "read")
access: access allowed ("java.util.PropertyPermission" "os.version" "read")
access: access allowed ("java.util.PropertyPermission" "swing.useSystemFontSettings" "read")
access: access allowed ("java.util.PropertyPermission" "os.name" "read")
access: access allowed ("java.util.PropertyPermission" "java.home" "read")
access: access allowed ("java.io.FilePermission" "C:\Program Files\Java\jre1.8.0_121\lib\swing.properties" "read")
access: access allowed ("java.lang.reflect.ReflectPermission" "suppressAccessChecks")
access: access allowed ("java.util.PropertyPermission" "os.version" "read")
access: access allowed ("java.util.PropertyPermission" "user.dir" "read")
access: access allowed ("java.io.FilePermission" "C:\etc\release" "read")
access: access allowed ("java.io.FilePermission" "\etc\release" "read")
access: access allowed ("java.util.PropertyPermission" "swing.showFromDoubleBuffer" "read")
access: access allowed ("java.util.PropertyPermission" "swing.nativeErase" "read")
access: access denied ("java.awt.AWTPermission" "showWindowWithoutWarningBanner")
access: access allowed ("java.util.PropertyPermission" "awt.appletWarning" "read")
access: access allowed ("java.util.PropertyPermission" "java.home" "read")
access: access allowed ("java.util.PropertyPermission" "sun.awt.nopixfmt" "read")
access: access allowed ("java.util.PropertyPermission" "swing.logDoubleBufferingDisable" "read")
access: access allowed ("java.util.PropertyPermission" "swing.ignoreDoubleBufferingDisable" "read")
access: access allowed ("java.lang.RuntimePermission" "createClassLoader")
access: access allowed ("java.lang.RuntimePermission" "createClassLoader")
access: access allowed ("java.lang.RuntimePermission" "accessClassInPackage.sun.reflect.misc")
.. (removed for brevity)
access: access allowed ("java.util.PropertyPermission" "os.name" "read")
access: access allowed ("java.util.PropertyPermission" "java.util.prefs.PreferencesFactory" "read")
access: access allowed ("java.util.PropertyPermission" "os.name" "read")
access: access allowed ("java.lang.reflect.ReflectPermission" "suppressAccessChecks")
access: access denied ("java.lang.RuntimePermission" "preferences")
Exception in thread "AWT-EventQueue-0" java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "preferences")
        at java.security.AccessControlContext.checkPermission(Unknown Source)
        at java.security.AccessController.checkPermission(Unknown Source)
        at java.lang.SecurityManager.checkPermission(Unknown Source)
        at java.util.prefs.Preferences.userRoot(Unknown Source)
        at e.<init>(Unknown Source)
        at e.<init>(Unknown Source)
        at MyApp.<init>(Unknown Source)
        at a.run(Unknown Source)
        at java.awt.event.InvocationEvent.dispatch(Unknown Source)
        at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
        at java.awt.EventQueue.access$500(Unknown Source)
        at java.awt.EventQueue$3.run(Unknown Source)
        at java.awt.EventQueue$3.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
        at java.awt.EventQueue.dispatchEvent(Unknown Source)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
        at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
        at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
        at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
        at java.awt.EventDispatchThread.run(Unknown Source)
更新进一步调试显示了Java中的一个bug??我已在策略文件中精确匹配了“活动代码源”,但它仍然拒绝它:

grant codeBase "file:/-" {
 permission java.security.AllPermission;
};

grant codeBase "file://global/fs/Technology/Tools/MyApp.jar" {
 permission java.security.AllPermission;
};

grant {
 permission java.net.SocketPermission "*", "accept,connect,resolve";
};
通过
policy
调试,我看到了以下情况(我注意到
file://-
更改为仅允许我当前的C:驱动器):

C:\Users\Default>java-Djava.security.manager-Djava.security.policy=mypolicy-Djava.security.debug=policy-jar\\global\fs\Technology\Tools\MyApp.jar
策略:评估代码源:
策略代码源:(文件:/C:/-)
活动代码源:(file://global/fs/Technology/Tools/MyApp.jar )
策略:评估(代码源)失败
策略:评估代码源:
政策代码来源:(file://global/fs/Technology/Tools/MyApp.jar )
活动代码源:(file://global/fs/Technology/Tools/MyApp.jar )
策略:评估(代码源)失败
策略:评估代码源:
策略代码源:(null)
活动代码源:(file://global/fs/Technology/Tools/MyApp.jar )
政策:评估校长:
政策负责人:[]
主动主体:[]
策略:授予(“java.net.SocketPermission”“*”“连接、接受、解析”)
如您所见,它将“策略代码源”与“活动代码源”进行比较,并说它们不匹配,即使它们是相同的?!?因为它们不匹配,所以我的通用授权块只能授予有限的权限

只有当当前工作目录与JAR文件位于不同的驱动器或文件系统上时,才会出现这种情况


无论路径如何,都不能授予“MyApp.jar”权限吗?

使用前斜杠。不是单反斜杠和双反斜杠的混合。我试过
grant codeBase“file://global/fs/Technology/Tools/MyApp.jar“
以及
grant codeBase”文件:/global/fs/Technology/Tools/MyApp.jar”
具有相同的结果。
grant codeBase "file:/-" {
 permission java.security.AllPermission;
};

grant codeBase "file://global/fs/Technology/Tools/MyApp.jar" {
 permission java.security.AllPermission;
};

grant {
 permission java.net.SocketPermission "*", "accept,connect,resolve";
};
C:\Users\Default> java -Djava.security.manager -Djava.security.policy=mypolicy -Djava.security.debug=policy -jar \\global\fs\Technology\Tools\MyApp.jar

policy: evaluate codesources:
  Policy CodeSource: (file:/C:/- <no signer certificates>)
  Active CodeSource: (file://global/fs/Technology/Tools/MyApp.jar <no signer certificates>)
policy: evaluation (codesource) failed

policy: evaluate codesources:
  Policy CodeSource: (file://global/fs/Technology/Tools/MyApp.jar <no signer certificates>)
  Active CodeSource: (file://global/fs/Technology/Tools/MyApp.jar <no signer certificates>)
policy: evaluation (codesource) failed

policy: evaluate codesources:
  Policy CodeSource: (null <no signer certificates>)
  Active CodeSource: (file://global/fs/Technology/Tools/MyApp.jar <no signer certificates>)
policy: evaluate principals:
  Policy Principals: []
  Active Principals: []
policy:   granting ("java.net.SocketPermission" "*" "connect,accept,resolve")