
本文详解 JavaEE 环境下 MDB 连接 IBM MQ 时出现 JMSWMQ2013 安全异常的根本原因,结合 AMQERR01.LOG 日志分析、CHLAUTH 与 CONNAUTH 配置逻辑、资源适配器默认行为及 JBoss/WildFly 的隐式用户映射机制,提供可落地的零认证连接配置方案。
本文详解 javaee 环境下 mdb 连接 ibm mq 时出现 `jmswmq2013` 安全异常的根本原因,结合 `amqerr01.log` 日志分析、chlauth 与 connauth 配置逻辑、资源适配器默认行为及 jboss/wildfly 的隐式用户映射机制,提供可落地的零认证连接配置方案。
在 JavaEE 应用中通过 MDB(Message-Driven Bean)连接 IBM MQ 时,即使队列管理器已明确禁用通道认证(CHLAUTH(DISABLED)),仍频繁报出 JMSWMQ2013: The security authentication was not valid 错误——这并非表面的“用户名密码错误”,而是 IBM MQ 返回的通用拒绝码 MQRC_NOT_AUTHORIZED (2035) 的客户端封装。关键在于:MQ 的 2035 错误涵盖多种授权失败场景,而客户端仅收到模糊提示;真正线索必须从服务端日志中挖掘。
您提供的 AMQERR01.LOG 片段已给出决定性证据:
AMQ8077W: Entity 'jboss' has insufficient authority to access object QMGR [qmgr]. AMQ9557E: Queue Manager User ID initialization failed for 'jboss'.
这说明:MQ 实际尝试以操作系统用户 jboss(即运行 JBoss/WildFly 进程的 UID)进行连接认证,而非空字符串或匿名用户。 尽管 MCAUSER('') 和 CHLAUTH(DISABLED) 已配置,但 IBM MQ v9.2+ 默认启用 CONNAUTH(连接认证),其底层依赖于 AUTHINFO 对象定义的认证方式。您日志中显示:
CONNAUTH(DEV.AUTHINFO)
即队列管理器强制使用名为 DEV.AUTHINFO 的认证信息对象——而该对象极大概率是 IBM MQ 安装默认创建的 SYSTEM.DEFAULT.AUTHINFO.IDPWOS 类型,它要求提供有效 OS 用户凭据(即使通道层不校验,连接层仍会校验)。因此,CHLAUTH(DISABLED) 仅关闭通道级规则匹配,无法绕过 CONNAUTH 所触发的用户上下文初始化流程。
立即学习“Java免费学习笔记(深入)”;
✅ 正确解法:彻底禁用 CONNAUTH 并显式指定匿名上下文
步骤 1:修改 authentication.mqsc,禁用 CONNAUTH 并重置默认 AUTHINFO
-- 彻底禁用连接认证(关键!)
ALTER QMGR CONNAUTH('')
-- 清除默认 AUTHINFO 引用,避免 fallback
RESET QMGR
-- (可选)删除或禁用 DEV.AUTHINFO
DELETE AUTHINFO(DEV.AUTHINFO)⚠️ 注意:
ALTER QMGR CONNAUTH('')是禁用 CONNAUTH 的唯一标准方式。设置为''表示“无认证信息”,而非留空字符串。执行后需重启队列管理器(endmqm QMGR && strmqm QMGR)。
步骤 2:确保 config.mqsc 中 MCAUSER 显式设为空,并启用 ADOPTCTX
DEFINE CHANNEL(MY.CHANNEL) +
CHLTYPE(SVRCONN) +
TRPTYPE(TCP) +
MCAUSER('') +
ADOPTCTX(YES) + -- 允许客户端传递空上下文(关键兼容项)
REPLACEADOPTCTX(YES) 告知 MQ 接受客户端声明的用户上下文(此处为空),避免强制映射到 OS 用户。
步骤 3:在 JBoss/WildFly 的 standalone.xml 中显式禁用凭证传递
IBM MQ 资源适配器(wmq.jmsra.rar)在 CLIENT 模式下,默认会将应用服务器进程用户(如 jboss)作为 userID 发送给 MQ,这正是日志中 Entity 'jboss' 的来源。需通过配置覆盖此行为:
<connection-definition
class-name="com.ibm.mq.connector.outbound.ManagedConnectionFactoryImpl"
jndi-name="${jms.connectionfactory.jndi}"
use-java-context="false"
pool-name="connection-definition">
<!-- ... 其他 config-property ... -->
<!-- 关键:显式设置空用户名,覆盖默认行为 -->
<config-property name="userName"></config-property>
<config-property name="password"></config-property>
<!-- 禁用自动用户推断 -->
<config-property name="useConnectionPool">true</config-property>
</connection-definition>?
userName和password为空字符串(非 null)将强制 MQ 使用匿名上下文,与MCAUSER('')和ADOPTCTX(YES)协同生效。
步骤 4:验证与测试
- 重启 IBM MQ 容器(确保
setup.sh中runmqsc顺序正确:先ALTER QMGR再strmqm); - 进入容器执行
dspmqaut -m QMGR -t qmgr,确认输出中无connect权限拒绝; - 在 JBoss 中部署 MDB,观察
AMQERR01.LOG不再出现AMQ8077W或AMQ9557E。
? 补充说明:为什么 CHLAUTH(DISABLED) 不够?
-
CHLAUTH控制通道级规则匹配(如 IP 白名单、用户映射),而CONNAUTH控制连接建立时的用户上下文初始化; - 即使
CHLAUTH关闭,只要CONNAUTH非空,MQ 仍会尝试解析userID,此时若未提供有效凭据或MCAUSER不匹配,即触发 2035; - Docker 环境中,
jboss用户是容器内进程 UID,非 MQ 认知的合法用户,故必须通过CONNAUTH('')+MCAUSER('')+ADOPTCTX(YES)+userName=""四重保障实现真·免认证。
遵循上述配置,即可在 IBM MQ 9.2.4+ 与 JavaEE MDB 间建立稳定、安全、无需凭证的 CLIENT 模式连接,兼顾开发效率与生产环境最小权限原则。


















