【问题标题】:MQQueueManager constructor hangs when a SecurityManager is installed安装 SecurityManager 时 MQQueueManager 构造函数挂起
【发布时间】:2018-06-06 17:16:04
【问题描述】:

主机 foo 是一个 IBM MQ 客户端(即通过 TCP/IP 的客户端模式连接)。主机栏是运行队列管理器的系统。 Bar 授予 foo 实例化 com.ibm.mq.MQQueueManager 对象的权限(通过 IP 地址),但不授予托管 foobar 的权限。

因此,我将所有 IBM MQ 联系人封装到一个在 foo 上运行的新应用程序中。与 foobar 一起,正在形成一个客户端/服务器应用程序,使用套接字,其中 foo 是服务器,而 foobar 是客户端。和以前一样,Foo 仍然是 IBM MQ 客户端。

到目前为止,我在新应用程序(MQ 相关)中尝试对 foo 做的只是实例化一个 MQQueueManager 对象。成功了,直到我介绍 java.lang.SecurityManager。

通过 java 命令执行的本地应用程序,例如 foo 上的这个应用程序,默认情况下不会在安装了 SecurityManager 的情况下运行。现在它在安装了 SecurityManager 的情况下运行。原因是控制对在 foo 上运行的这个应用程序的访问。安全策略接受来自 foobar (java.net.SocketPermission) 的连接。这行得通。 foo 的所有者现在可以控制授予 foobar 的权限。

但是我们在 foo 和 bar 之间的交互中受到了一些干扰。干扰来自 SecurityManager。不要在安装了 SecurityManager 的情况下运行,并且 foo 可以实例化 MQQueueManager。使用 SecurityManager 运行,并且 foo 在 MQQueueManager 构造函数中挂起。

Foo 正在使用 https://docs.oracle.com/javase/7/docs/technotes/guides/security/PolicyFiles.html 中描述的 Policy 参考实现

对 foo 的以下权限导致 MQQueueManager 构造函数挂起。

permission java.net.SocketPermission "bar", "connect, accept";

-Dcom.ibm.msg.client.commonservices.trace.status=ON

-Djava.security.debug="access,failure"

... access denied ("java.util.PropertyPermission" "mqs.disable.all.intercept" "read") [java.security.AccessControlException] ...

... access denied ("java.util.PropertyPermission" "mqs.intercept.serializeconn" "read") [java.security.AccessControlException] ...

【问题讨论】:

  • 只是为了澄清问题,我从您的问题中了解到,您正试图使用​​ SecurityManager 通过 IP 地址或主机名锁定从另一个应用程序到您的应用程序的连接,其次您必须允许您的应用程序作为 MQ 客户端连接到队列管理器,您尝试为 MQ 客户端到 MQ 服务器连接添加的安全性不是额外的。
  • MQ 版本,从每个具有 MANIFEST.MF 文件的 com.ibm.mq*.jar 文件来看,似乎是 8.0.0.3。
  • 是的,我怀疑那个“连接”操作应该已经足够了。这里的挑战是 MQQueueManager 构造函数是一个黑盒子。
  • 您的“只是为了澄清”的评论是完全正确的。 Foo 独自拥有 MQ 的访问权限(在 bar 上)。我不想违反它的精神,所以我让 foo 的所有者控制扩展(抽象)对 foobar 的访问。
  • 查看我提供的链接我没有看到提到的那些特定属性,但我建议添加这个并重试permission java.util.PropertyPermission "mqs.*","read";

标签: java ibm-mq securitymanager


【解决方案1】:

IBM MQ v8 KC 有一个页面“Running IBM MQ classes for Java applications under the Java Security Manager”。

此页面说明与 MQ 客户端连接相关:

//For the client transport type.
permission java.net.SocketPermission "*","connect,resolve";

我唯一注意到的是,与您发布的内容相比,上述示例中缺少空格,您也不需要提供 accept 权限,而且我还在 sun 文档中指出 resolve 隐含在 @ 987654325@ 所以应该不是特别需要。

还有很多其他设置与您可能需要的其他权限相关,因此我建议您查看以上页面了解更多详情。


您可以使用以下 java 系统属性获取 IBM MQ Classes for Java 跟踪:

-Dcom.ibm.msg.client.commonservices.trace.status=ON

默认情况下,跟踪将输出到当前目录中名为 mqjms_%PID%.trc 的文件,而 %PID% 将替换为您的 java 进程的进程 ID。

如果要指定不同的文件名或路径,可以添加以下 java 系统属性:

-Dcom.ibm.msg.client.commonservices.trace.outputName=/tmp/x/y/z/mqjms_%PID%.trc 

两者的示例命令:

java -Dcom.ibm.msg.client.commonservices.trace.status=ON -Dcom.ibm.msg.client.commonservices.trace.outputName=mqjms_%PID%.trc SomeJavaApp

java 安全管理器跟踪可能会有所帮助,您可以通过添加以下 java 系统属性来启用它:

-Djava.security.debug="access,failure"

【讨论】:

  • 所有尝试接受此答案或将其标记为有用的结果都会导致来自 Stack Overflow 的错误消息。 “发生错误 - 请重试您的请求。”
【解决方案2】:

但是我们在 foo 和 酒吧。干扰来自 SecurityManager。不要跑 安装了 SecurityManager 并且 foo 可以实例化 MQ 队列管理器。使用 SecurityManager 运行并且 foo 挂在 MQQueueManager 构造函数。

这很奇怪。 MQ 文档中的哪个位置说要使用 Java SecurityManager。有人给了你不好的信息。此外,您不使用 SecurityManager 进行 MQ 安全性。

对 foo 的以下权限会导致 MQQueueManager 构造函数挂起。 权限 java.net.SocketPermission "bar", "connect, accept";

为什么要限制 MQ 客户端库的功能?如果它无法侦听和解析 tcp 通信,那么它将无法工作。只需删除该行。

【讨论】:

  • MQ 文档中的什么地方说我不能使用 Java SecurityManager 来限制对 foo 的访问?明白了 foobar 就是对 IBM MQ 一无所知,只是在 foo 上有一些队列可以访问。我不想以任何方式限制 MQ 客户端库可以做什么。当存在任何其他动作时,暗示“解决”动作。 “listen”操作仅在与“localhost”一起使用时才有意义,并且意味着能够绑定到指定端口。删除该行甚至完全拒绝“连接”和“接受”操作。
  • 我创建 Java/MQ 客户端应用程序已经超过 15 年了。我已经创建了 100 个,其中最著名的一个是 MQ Visual Edit。这些年来我从未想过让我使用 SecurityManager 类来应用安全性。确保安全的正确方法是在队列管理器中使用 CONNAUTH(用于身份验证)、CHLAUTH(用于过滤)和 setmqaut(用于授权)。
猜你喜欢
  • 2018-02-23
  • 1970-01-01
  • 2020-05-22
  • 2018-02-28
  • 2016-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-17
相关资源
最近更新 更多