【问题标题】:Disable "internet access" for JVM?禁用 JVM 的“互联网访问”?
【发布时间】:2014-09-05 08:31:28
【问题描述】:

我想知道是否有办法告诉 JVM 它无法连接到某个 Java 程序的任何 Web 资源,或者在这样做时立即失败,即做一个相当于关闭互联网的软件使用硬件开关访问。 这是为了协助自动化测试,禁用系统的防火墙对我来说是没有选择的。

背景: 我目前正在处理一个 Java 问题,其中 XML 身份转换不适用于 XML 中引用的 DOCTYPE,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="32px"
     height="32px" viewBox="0 0 32 32" enable-background="new 0 0 32 32" xml:space="preserve">
<!-- content.... -->
</svg>

DocumentBuilderFactory、TransformerFactory 等的标准行为是访问网络以查找缺失的实体。 虽然建议的修复程序 https://stackoverflow.com/a/9398602/1143126(一个 NullEntityResolver)解决了我的大部分问题,但我想在“离线环境”中以自动方式测试此功能以进行回归。

【问题讨论】:

  • 这能回答你的问题吗? stackoverflow.com/questions/4645588/…
  • 我肯定会选择 Java Security。如果可以保证 JVM 范围内的任何事情,就是这样。
  • @Dunes 看起来很有希望,谢谢!我应该搜索“网络连接”而不是“互联网连接”...

标签: java


【解决方案1】:

Dunes 的评论帮助很大(问题How to disable all network connections in Java 是相关的),我忽略了另一个问题。

以下是我将用来阻止网络连接的方法:

  • 使用 JVM 参数启动测试用例 -Djava.security.manager=default -Djava.security.policy=/java.policy
  • 作为 java.policy,我使用我在 Java 安装中找到的默认文件,并添加了以下行 s.t.东西适用于 TestNG:

    // // additional permissions for running TestNG // // 
    
    // TestNG reads a lot of properties...
    permission java.util.PropertyPermission "*", "read";
    
    // TestNG connects to a local port for debugging, and does some reflection magic
    permission java.net.SocketPermission "127.0.0.1:*", "connect,resolve";
    permission java.lang.RuntimePermission "accessDeclaredMembers";
    permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
    
    // needs at least read access to (default) test suite folder location
    permission java.io.FilePermission "C:/Users/<me>/AppData/Local/Temp/-", "read, write";
    
    // if the test case (or, data provider) accesses any other files, add their location. or do it the lazy way:
    permission java.io.FilePermission "C:/-", "read, write";
    

使用该配置,任何对外部源(例如 www.w3.org)的访问都将导致 AccessControlException:

javax.xml.transform.TransformerException: java.security.AccessControlException: access denied (java.net.SocketPermission www.w3.org:80 connect,resolve)

【讨论】:

    【解决方案2】:

    您可以使用XML catalog 在本地磁盘上存储外部架构 (xsd+dtd)。这也加快了正常处理速度,并允许快速离线开发。

    这是一种标准机制。

    (对于 XHTML 尤其有价值,因为有大量的 HTML 实体。)

    【讨论】:

    • 很好的提示,谢谢!我想这比我的 NullEntityResolver 更干净。但我想这需要一些努力来了解如何配置......
    • 我不记得所做的努力,但是是的,完全开箱即用的配置不是。事实上,我首先做了一个实体解析器来从 PUBLIC 切换到 SYSTEM(本地磁盘)。但这也是开销。
    【解决方案3】:

    诚然,我还没有对此进行测试,但我认为应该可以创建java.net.SocketImplFactory,它创建SocketImpls,在例如。 connect 被调用。

    正如其他人所指出的,还可以定义安全管理器。我猜主要的区别是会抛出什么样的异常。我认为没有任何方法可以防止这种解决方案抛出SecurityExceptions 而不是SocketExceptions 或其他IOExceptions,这对于正确测试错误处理代码可能很重要。

    【讨论】:

    • @MarkoTopolnik:如果你使用Socket.setSocketImplFactory设置它,至少所有使用java.net.Sockets的代码都会被强制使用它。
    • 只能调用一次。然而,你对 NIO 的看法是正确的。不过,这可能是也可能不是问题,具体取决于 OP 的情况。我不能说我知道 XML 处理工具是使用java.net 还是 NIO。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-18
    • 2016-11-06
    • 2018-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-02
    相关资源
    最近更新 更多