IBM MQ 调用失败,compcode“2”('MQCC_FAILED')原因“2035”('MQRC_NOT_AUTHORIZED')
IBM MQ call failed with compcode '2' ('MQCC_FAILED') reason '2035' ('MQRC_NOT_AUTHORIZED')
我在尝试连接到我所在机构的 MQ v9 时遇到困难。
MQ 团队向我提供了连接信息:-
String hostName = '...'
int port = ...
String queueManager = '...'
String channel = '...'
String userId = 'ABC123'
String password = '...'
给定以下代码...
JmsConnectionFactory cf = JmsFactoryFactory.
getInstance(WMQConstants.WMQ_PROVIDER).
createConnectionFactory()
cf.setStringProperty(WMQConstants.WMQ_HOST_NAME, hostName)
cf.setIntProperty(WMQConstants.WMQ_PORT, port)
cf.setStringProperty(WMQConstants.WMQ_CHANNEL, channel)
cf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT)
cf.setStringProperty(WMQConstants.WMQ_QUEUE_MANAGER, queueManager)
cf.setStringProperty(WMQConstants.USERID, userId)
cf.setStringProperty(WMQConstants.PASSWORD, password)
// tried with both `true` and `false`... same error
cf.setBooleanProperty(WMQConstants.USER_AUTHENTICATION_MQCSP, true)
Connection connection = cf.createConnection()
connection.start()
connection.close()
...我收到此错误:-
Exception in thread "main" com.ibm.msg.client.jms.DetailedJMSSecurityException:
JMSWMQ2013: The security authentication was not valid
that was supplied for queue manager '...' with connection
mode 'Client' and host name '...'.
Please check if the supplied username and password
are correct on the queue manager to which you are
connecting.
Caused by: com.ibm.mq.MQException: JMSCMQ0001: IBM
MQ call failed with compcode '2' ('MQCC_FAILED') reason
'2035' ('MQRC_NOT_AUTHORIZED').
MQ 团队告诉我,日志中有这样的内容:-
----- amqzfuca.c : 4527 -------------------------------------------------------
04/17/2019 10:32:20 AM - Process(10468.40757) User(...) Program(...)
Host(...) Installation(Installation1)
VRMF(9.1.0.1) QMgr(...)
Time(2019-04-17T15:32:20.542Z)
RemoteHost(...)
CommentInsert1(...)
CommentInsert2(...)
CommentInsert3(CLNTUSER(XYZ) ADDRESS(...))
AMQ9777E: Channel was blocked
EXPLANATION:
The inbound channel '...' was blocked from address '...'
because the active values of the channel matched a record
configured with USERSRC(NOACCESS). The active values of the channel were
'CLNTUSER(XYZ) ADDRESS(...)'.
... 它失败了,因为它使用了错误的凭据进行连接。
虽然我传入了不同的凭据(用户 ID:ABC123),但 MQ 日志会看到我用来登录我的机器的用户 ID(用户 ID:XYZ)。
为什么我明确输入的凭据被遗漏了?我该如何解决这个问题?
我正在使用这个依赖项:
<dependency>
<groupId>com.ibm.mq</groupId>
<artifactId>com.ibm.mq.allclient</artifactId>
<version>9.1.2.0</version>
</dependency>
我没有使用 IBM JRE...更准确地说,我在 Mac 上使用 Oracle JDK 1.8,如果有帮助的话。
谢谢。
更新 2019-04-22
我现在能够从 MQ 团队获得更准确的日志,因为我同时尝试了太多事情。
如果我将 USER_AUTHENTICATION_MQCSP
设置为 true
,那么我的机器的用户 ID (XYZ) 将被传入。
如果我将 USER_AUTHENTICATION_MQCSP
设置为 false
,那么我现在会收到不同的错误消息:-
04/22/2019 01:19:49 PM - Process(1147099.9759) User(...) Program(...)
Host(rofesb911a) Installation(Installation1)
VRMF(9.1.0.1) QMgr(...)
Time(2019-04-22T18:19:49.323Z)
RemoteHost(...)
CommentInsert1(wa03598)
CommentInsert2(REQUIRED)
CommentInsert3(MCAUSER(ABC123) CLNTUSER(ABC123) ADDRESS(...))
AMQ9790I: The failed authentication check was caused by a CHLAUTH record with
CHCKCLNT(REQUIRED).
EXPLANATION:
The user ID 'ABC123' and its password were checked because the inbound
connection matched a channel authentication record with CHCKCLNT(REQUIRED).
The active values of the channel were 'MCAUSER(ABC123) CLNTUSER(ABC123)
ADDRESS(...)'. The MATCH(RUNCHECK) mode of the DISPLAY CHLAUTH
MQSC command can be used to identify the relevant CHLAUTH record.
好消息是它看到了正确的用户 ID (ABC123),但我被告知密码无效。我不认为这是密码问题,因为我能够使用相同的凭据访问其他受保护的 Web 服务。
您的 MQ 团队已为您提供了要使用的凭据(即用户 ID 和密码),因此我假设他们已经在队列管理器上打开了用户 ID 和密码检查。
队列管理器未使用 ADOPTCTX(是)
ADOPTCTX(YES) 是队列管理器上的一个设置,表明一旦用户 ID 和密码被验证为正确,用户 ID(在您的情况下 "ABC123")应该用于所有进一步的安全检查(例如,我可以使用这个队列)。如果此设置为 NO,则在密码验证完成后,它实际上将使用客户端计算机登录的用户 ID,该用户 ID 也被发送到队列管理器(在您的情况下 "XYZ")。您的队列管理器可能就是这种情况。
USER_AUTHENTICATION_MQCSP模式
实际上有两种方法可以将用户 ID 和密码从 Java 客户端应用程序发送到队列管理器。
- 第一个(已有数十年历史)在 IBM MQ V8 之前使用,并使用了限制长度的流(每个字段最多 12 个字符),最初用于 DOS SNA 客户端将两个字段发送到 QMgr。这种跨网络的流也是将登录用户 ID 的客户端发送到队列管理器的方式,因此只能发送一个。
- 在 MQ V6 中添加的较新结构是 MQCSP 结构,它在 MQ V8 的队列管理器中本地检查密码时更加有用,它允许可变长度的用户 ID 和密码字段。这是一个不同于发送客户端登录用户 ID 的网络流,因此两者都被发送到队列管理器。
当您将 USER_AUTHENTICATION_MQCSP
设置为 true 时,您是在告诉 Java 客户端使用第二种模式。这提供了被 ADOPTCTX(NO) 设置绊倒的机会。如果将其设置为 false,则进入队列管理器的唯一用户 ID 是 ABC123(在您的示例中),并且可能会给您一个不同的,也许是成功的结果。
尝试将您的应用程序 USER_AUTHENTICATION_MQCSP
设置为 false,当它起作用时,建议您的 MQ 团队他们应该使用 ADOPTCTX(YES),这也是现在的默认值,然后您可以切换回 USER_AUTHENTICATION_MQCSP
设为真。
我在尝试连接到我所在机构的 MQ v9 时遇到困难。
MQ 团队向我提供了连接信息:-
String hostName = '...'
int port = ...
String queueManager = '...'
String channel = '...'
String userId = 'ABC123'
String password = '...'
给定以下代码...
JmsConnectionFactory cf = JmsFactoryFactory.
getInstance(WMQConstants.WMQ_PROVIDER).
createConnectionFactory()
cf.setStringProperty(WMQConstants.WMQ_HOST_NAME, hostName)
cf.setIntProperty(WMQConstants.WMQ_PORT, port)
cf.setStringProperty(WMQConstants.WMQ_CHANNEL, channel)
cf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT)
cf.setStringProperty(WMQConstants.WMQ_QUEUE_MANAGER, queueManager)
cf.setStringProperty(WMQConstants.USERID, userId)
cf.setStringProperty(WMQConstants.PASSWORD, password)
// tried with both `true` and `false`... same error
cf.setBooleanProperty(WMQConstants.USER_AUTHENTICATION_MQCSP, true)
Connection connection = cf.createConnection()
connection.start()
connection.close()
...我收到此错误:-
Exception in thread "main" com.ibm.msg.client.jms.DetailedJMSSecurityException:
JMSWMQ2013: The security authentication was not valid
that was supplied for queue manager '...' with connection
mode 'Client' and host name '...'.
Please check if the supplied username and password
are correct on the queue manager to which you are
connecting.
Caused by: com.ibm.mq.MQException: JMSCMQ0001: IBM
MQ call failed with compcode '2' ('MQCC_FAILED') reason
'2035' ('MQRC_NOT_AUTHORIZED').
MQ 团队告诉我,日志中有这样的内容:-
----- amqzfuca.c : 4527 -------------------------------------------------------
04/17/2019 10:32:20 AM - Process(10468.40757) User(...) Program(...)
Host(...) Installation(Installation1)
VRMF(9.1.0.1) QMgr(...)
Time(2019-04-17T15:32:20.542Z)
RemoteHost(...)
CommentInsert1(...)
CommentInsert2(...)
CommentInsert3(CLNTUSER(XYZ) ADDRESS(...))
AMQ9777E: Channel was blocked
EXPLANATION:
The inbound channel '...' was blocked from address '...'
because the active values of the channel matched a record
configured with USERSRC(NOACCESS). The active values of the channel were
'CLNTUSER(XYZ) ADDRESS(...)'.
... 它失败了,因为它使用了错误的凭据进行连接。
虽然我传入了不同的凭据(用户 ID:ABC123),但 MQ 日志会看到我用来登录我的机器的用户 ID(用户 ID:XYZ)。
为什么我明确输入的凭据被遗漏了?我该如何解决这个问题?
我正在使用这个依赖项:
<dependency>
<groupId>com.ibm.mq</groupId>
<artifactId>com.ibm.mq.allclient</artifactId>
<version>9.1.2.0</version>
</dependency>
我没有使用 IBM JRE...更准确地说,我在 Mac 上使用 Oracle JDK 1.8,如果有帮助的话。
谢谢。
更新 2019-04-22
我现在能够从 MQ 团队获得更准确的日志,因为我同时尝试了太多事情。
如果我将 USER_AUTHENTICATION_MQCSP
设置为 true
,那么我的机器的用户 ID (XYZ) 将被传入。
如果我将 USER_AUTHENTICATION_MQCSP
设置为 false
,那么我现在会收到不同的错误消息:-
04/22/2019 01:19:49 PM - Process(1147099.9759) User(...) Program(...)
Host(rofesb911a) Installation(Installation1)
VRMF(9.1.0.1) QMgr(...)
Time(2019-04-22T18:19:49.323Z)
RemoteHost(...)
CommentInsert1(wa03598)
CommentInsert2(REQUIRED)
CommentInsert3(MCAUSER(ABC123) CLNTUSER(ABC123) ADDRESS(...))
AMQ9790I: The failed authentication check was caused by a CHLAUTH record with
CHCKCLNT(REQUIRED).
EXPLANATION:
The user ID 'ABC123' and its password were checked because the inbound
connection matched a channel authentication record with CHCKCLNT(REQUIRED).
The active values of the channel were 'MCAUSER(ABC123) CLNTUSER(ABC123)
ADDRESS(...)'. The MATCH(RUNCHECK) mode of the DISPLAY CHLAUTH
MQSC command can be used to identify the relevant CHLAUTH record.
好消息是它看到了正确的用户 ID (ABC123),但我被告知密码无效。我不认为这是密码问题,因为我能够使用相同的凭据访问其他受保护的 Web 服务。
您的 MQ 团队已为您提供了要使用的凭据(即用户 ID 和密码),因此我假设他们已经在队列管理器上打开了用户 ID 和密码检查。
队列管理器未使用 ADOPTCTX(是)
ADOPTCTX(YES) 是队列管理器上的一个设置,表明一旦用户 ID 和密码被验证为正确,用户 ID(在您的情况下 "ABC123")应该用于所有进一步的安全检查(例如,我可以使用这个队列)。如果此设置为 NO,则在密码验证完成后,它实际上将使用客户端计算机登录的用户 ID,该用户 ID 也被发送到队列管理器(在您的情况下 "XYZ")。您的队列管理器可能就是这种情况。
USER_AUTHENTICATION_MQCSP模式
实际上有两种方法可以将用户 ID 和密码从 Java 客户端应用程序发送到队列管理器。
- 第一个(已有数十年历史)在 IBM MQ V8 之前使用,并使用了限制长度的流(每个字段最多 12 个字符),最初用于 DOS SNA 客户端将两个字段发送到 QMgr。这种跨网络的流也是将登录用户 ID 的客户端发送到队列管理器的方式,因此只能发送一个。
- 在 MQ V6 中添加的较新结构是 MQCSP 结构,它在 MQ V8 的队列管理器中本地检查密码时更加有用,它允许可变长度的用户 ID 和密码字段。这是一个不同于发送客户端登录用户 ID 的网络流,因此两者都被发送到队列管理器。
当您将 USER_AUTHENTICATION_MQCSP
设置为 true 时,您是在告诉 Java 客户端使用第二种模式。这提供了被 ADOPTCTX(NO) 设置绊倒的机会。如果将其设置为 false,则进入队列管理器的唯一用户 ID 是 ABC123(在您的示例中),并且可能会给您一个不同的,也许是成功的结果。
尝试将您的应用程序 USER_AUTHENTICATION_MQCSP
设置为 false,当它起作用时,建议您的 MQ 团队他们应该使用 ADOPTCTX(YES),这也是现在的默认值,然后您可以切换回 USER_AUTHENTICATION_MQCSP
设为真。