【问题标题】:MQRC_NOT_AUTHORIZED when creating CCDT for MQ.NET Client为 MQ.NET 客户端创建 CCDT 时的 MQRC_NOT_AUTHORIZED
【发布时间】:2018-04-21 17:25:39
【问题描述】:

通过 .NET 客户端访问 MQ 服务器时出现以下错误。创建 CCDT 时不询问登录凭据。但是 MQ 服务器出于某种原因正在寻找它。

我找不到任何同时涵盖 CCDT 和以下错误的信息。

IBM.WMQ.MQException: MQRC_NOT_AUTHORIZED

----- cmqxrsrv.c : 2356 -------------------------------------------------------
    17/04/2018 23:50:44 - Process(1848.16) User(SYSTEM) Program(amqzlaa0.exe)
                          Host(APPLE) Installation(Installation1)
                          VRMF(8.0.0.5) QMgr(LocalQM)

    AMQ5540: Application 'bin\Debug\Producer.exe' did not supply a user ID
    and password

    EXPLANATION:
    The queue manager is configured to require a user ID and password, but none was
    supplied.
    ACTION:
    Ensure that the application provides a valid user ID and password, or change
    the queue manager configuration to OPTIONAL to allow applications to connect
    which have not supplied a user ID and password. 
    ----- amqzfuca.c : 4311 -------------------------------------------------------
    17/04/2018 23:50:44 - Process(1848.16) User(SYSTEM) Program(amqzlaa0.exe)
                          Host(APPLE) Installation(Installation1)
                          VRMF(8.0.0.5) QMgr(LocalQM)

    AMQ5541: The failed authentication check was caused by the queue manager
    CONNAUTH CHCKCLNT(REQDADM) configuration.

    EXPLANATION:
    The user ID 'mqclient' and its password were checked because the user ID is
    privileged and the queue manager connection authority (CONNAUTH) configuration
    refers to an authentication information (AUTHINFO) object named
    'SYSTEM.DEFAULT.AUTHINFO.IDPWOS' with CHCKCLNT(REQDADM). 

    This message accompanies a previous error to clarify the reason for the user ID
    and password check.
    ACTION:
    Refer to the previous error for more information. 

    Ensure that a password is specified by the client application and that the
    password is correct for the user ID. The authentication configuration of the
    queue manager connection determines the user ID repository. For example, the
    local operating system user database or an LDAP server. 

    To avoid the authentication check, you can either use an unprivileged user ID
    or amend the authentication configuration of the queue manager. You can amend
    the CHCKCLNT attribute in the CHLAUTH record, but you should generally not
    allow unauthenticated remote access. 
    -------------------------------------------------------------------------------
    17/04/2018 23:50:45 - Process(14900.9) User(SYSTEM) Program(amqrmppa.exe)
                          Host(APPLE) Installation(Installation1)
                          VRMF(8.0.0.5) QMgr(LocalQM)

    AMQ9557: Queue Manager User ID initialization failed for 'mqclient'.

    EXPLANATION:
    The call to initialize the User ID 'mqclient' failed with CompCode 2 and Reason
    2035.
    ACTION:
    Correct the error and try again. 
----- cmqxrsrv.c : 2356 -------------------------------------------------------

服务器设置

通过以下链接创建CCDT文件:

Setting up the server using IBM MQ Explorer

Server-connection Channel: LOCAL.DEF.SVRCONN

MCA User ID: empty

Setting up the client using IBM MQ Explorer

Clinet channe: LOCAL.DEF.SVRCONN

Queue Manager name: LocalQM

Connection name: 192.168.1.9(1415)

192.168.1.9 是本地主机地址

1415 是队列管理器,LocalQM,TCP 端口。

设置 CCDT 环境

1

C:\Users\'#.lp\source>SET MQCHLLIB=C:\ProgramData\IBM\MQ\qmgrs\LocalQM\@ipcc

C:\Users\'#.lp\source>SET MQCHLTAB=AMQCLCHL.TAB
  1. 将 AMQCLCHL.TAB 也放入 C:\ProgramData\IBM\MQ (我不知道为什么哪个可能不正确,因为日志文件出错:

    AMQ9518:找不到文件“C:\ProgramData\IBM\MQ\AMQCLCHL.TAB”。

)

IBM MQ.NET

下面的代码来自here

        MQQueueManager qm = null;
        System.Environment.SetEnvironmentVariable("MQCHLLIB", "C:\\ProgramData\\IBM\\MQ\\qmgrs\\LocalQM\\@ipcc");
        System.Environment.SetEnvironmentVariable("MQCHLTAB", "AMQCLCHL.TAB");

        try
        {
            Hashtable props = new Hashtable();
            props.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_CLIENT);
            qm = new MQQueueManager("LocalQM",props);
            MQQueue queue1 = qm.AccessQueue("LocalQueue", MQC.MQOO_OUTPUT | MQC.MQOO_FAIL_IF_QUIESCING);
            MQMessage msg = new MQMessage();
            msg.WriteUTF("Hello this message is from .net client");
            queue1.Put(msg);
            queue1.Close();
            qm.Disconnect();
        }
        catch (Exception ex)
        {
            Console.Write(ex);
        }

Windows 10 上的 IBM MQ V8

Windows 10 上的 MQ.NET 客户端 V8

Creating a client channel definition table

Using a client channel definition table with .NET

本帖与MQRC_Q_MGR_NAME_ERROR相关

更新 1

点击下面的链接。但似乎 MQ 服务器没有使用 mqccred.ini 上的信息。因为发生同样的错误。

Client side security exit to insert user ID and password ( mqccred )

设置步骤:

1 创建 mqccred.ini (D:\mqccred.ini)

QueueManager:
    Name=LocalQM
    User=mqclient
    password=password

2 设置 Windows 环境变量

set MQCCRED=D:\mqccred.ini

3 使用 mqccred

DEFINE CHANNEL(LOCAL.DEF.SVRCONN) CHLTYPE(clntconn) +
CONNAME(127.0.0.1) +
QMNAME(LocalQM) +
SCYEXIT('mqccred(ChlExit)') +
REPLACE

4 设置 ADOPTCTX(YES)

ALTER AUTHINFO(SYSTEM.DEFAULT.AUTHINFO.IDPWOS) AUTHTYPE(IDPWOS) ADOPTCTX(YES)

更新 2

我将 MQ 对象更新为大写,仍然得到与上面相同的错误,但下面有新的错误日志消息:

是否需要根据Using channel exits in IBM MQ .NET在.NET中编写退出程序?

22/04/2018 22:37:15 - Process(11904.1) User('#.lp) Program(mMq.Producer.exe)
                      Host(APPLE) Installation(Installation1)
                      VRMF(8.0.0.5)
AMQ9535: User exit not valid.

EXPLANATION:
Channel program 'LOCAL.DEF.SVRCONN' ended because user exit 'mqccred(ChlExit)'
is not valid. 
Architecture of the exit library does not match the process's architecture
  which is '' bit.
ACTION:
Ensure that the user exit is specified correctly in the channel definition, and
that the user exit program is correct and available. 
----- IBM.WMQ.MQChannelExitHandler.LoadExit : 0 -------------------------------
22/04/2018 22:38:21 - Process(5720.1) User('#.lp) Program(mMq.Producer.exe)
                      Host(APPLE) Installation(Installation1)
                      VRMF(8.0.0.5)
AMQ9535: User exit not valid.

EXPLANATION:
Channel program 'LOCAL.DEF.SVRCONN' ended because user exit 'mqccred(ChlExit)'
is not valid. 
Architecture of the exit library does not match the process's architecture
  which is '' bit.
ACTION:
Ensure that the user exit is specified correctly in the channel definition, and
that the user exit program is correct and available. 
----- IBM.WMQ.MQChannelExitHandler.LoadExit : 0 -------------------------------

更新 3

当 MCA 用户 ID 设置为 Windows 用户时,我在下面遇到不同的错误。

IBM.WMQ.MQException: MQRC_Q_MGR_NOT_AVAILABLE

22/04/2018 22:38:21 - Process(5720.1) User('#.lp) Program(mMq.Producer.exe)
                      Host(APPLE) Installation(Installation1)
                      VRMF(8.0.0.5)
AMQ9535: User exit not valid.

EXPLANATION:
Channel program 'LOCAL.DEF.SVRCONN' ended because user exit 'mqccred(ChlExit)'
is not valid. 
Architecture of the exit library does not match the process's architecture
  which is '' bit.
ACTION:
Ensure that the user exit is specified correctly in the channel definition, and
that the user exit program is correct and available. 
----- IBM.WMQ.MQChannelExitHandler.LoadExit : 0 -------------------------------

更新 4

很抱歉给您带来了困惑。更新 2 和 3 相同。两个更新应该有相同的错误:MQRC_Q_MGR_NOT_AVAILABLE,在更新 1 之后出现。我错误地输入了 MQRC_NOT_AUTHORIZED。

【问题讨论】:

  • 评论不用于扩展讨论;这个对话是moved to chat
  • 很抱歉给您带来了困惑,请参阅更新 4 进行解释。 2 和 3 是同一个错误。
  • 萍萍,你搞定了吗?
  • Pingpong,你搞定了吗?如果是这样,请接受一个有帮助的答案,如果您认为这是一个好的答案,请点赞。
  • 尚未尝试,在 .NET 中编写自己的退出会更复杂。我开始怀疑是否有比使用 exit 更好的方法来使用 CCDT。

标签: c# ibm-mq


【解决方案1】:

队列管理器名称:LocalQM

坏主意。你是在踢自己的脚。对队列管理器名称和 MQ 对象名称使用大写。一旦您是中级或高级 MQAdmin,就可以尝试使用大小写混合的名称。

定义通道(LOCAL.DEF.SVRCONN) CHLTYPE(clntconn) + CONNAME(127.0.0.1) + QMNAME(LocalQM) + SCYEXIT('mqccred(ChlExit)') + 替换

第一个问题:如果您不在 MQ 对象名称周围加上引号,那么 MQ 将自动将其大写!因此,MQ 会将您的命令视为 LOCALQM 而不是 LocalQM

第二个问题是您没有为 CONNAME 指定端口号。因此,MQ 将默认为 1414。但是您说您正在使用端口#1415

如果您不知道,MQ 对象名称区分大小写。

如果我是你,我会删除队列管理器 LocalQM 并从 LOCALQM 重新开始,并使用大写名称创建所有 MQ 对象。

使用 CCDT 不需要登录凭据,这是其中之一 使用 CCDT 的目的。

CCDT 条目仅包含连接信息。它们永远不会包含用户/应用程序凭据。要指定用户/应用程序凭据,您可以在应用程序中指定它们或使用 mqccred 客户端安全出口。

在这个时代,每个用户和每个应用程序都应该指定用户凭据,这样我们才能拥有一个安全的 MQ 环境。


2018 年 4 月 23 日更新

出口库的架构与进程的不匹配 ''位的架构。

架构是指程序的可寻址性或程序的运行框架。它是作为 32 位还是 64 位程序运行的。如果它作为 32 位程序运行,则需要使用 32 位 mqccred.dll,如果它作为 64 位程序运行,则需要使用 64 位 mqccred.dll。

我似乎记得一些关于 .NET 托管模式 (MQC.TRANSPORT_MQSERIES_MANAGED) 程序不能使用本机构建的出口的事情。您应该咨询 IBM 支持。

【讨论】:

    【解决方案2】:

    CCDT 的使用并没有消除向队列管理器证明身份的需要。您出现的第一个错误是因为默认情况下 MQ 需要管理员用户的密码。

    网络上的客户端连接有四个级别的 CONNAUTH:

    1. CHCKCLNT(REQDADM) 这是默认值。任何具有 MQ 管理权限的用户都必须提供有效密码。此外,任何没有管理权限但提供密码的用户都必须提供有效密码。
    2. CHKCLNT(OPTIONAL) 这与 #1 类似,但不需要为具有 MQ 管理权限的用户提供密码。任何提供密码的用户 Admin 都必须提供有效的密码,使用此值管理用户将不需要发送密码。
    3. CHCKCLNT(REQUIRED)这个值意味着所有用户都必须提供一个有效的密码。
    4. CHCKCLNT(NONE) 没有用户需要提供密码,即使他们提供了密码也不会被验证。

    您可以将 AUTHINFO 对象集上的整个队列管理器的此值设置为 QMGR 上的 CONNAUTH 值。如果将其设置为REQADMINOPTIONAL,则可以通过CHLAUTH 规则将特定频道的它提升为更严格的值,例如REQUIRED。你不能把它设置得更低。

    如果您禁用安全性,您将没有安全性,任何有权访问您的网络的人都可以连接到您的队列管理器。

    您有几个选项可以保持启用安全性:

    1. 您可以使用 CLNTCONN 上指定的客户端安全出口来传递 mqcred 等凭据。
    2. 您可以使用带有 TLS 的客户端证书并将其映射到 SVRCONN 上的 MCAUSER。

    请注意,根据您指定的 更新 1,您指定了 QMNAME(LocalQM),因为名称周围没有单引号 MQ 会将其折叠为大写并将其设置为 LOCALQM

    正如 Roger 指出的那样,您也没有在 CONNAME 上指定端口 1415 。您表示您遇到了问题,如果其中有 () 字符,则需要在 CONNAME 值周围​​加上单引号。


    基于您的 UPDATE 2 的注释(以下收集自移至 Chat 的 cmets):

    通常在Program FilesProgram Files(x86) 下的MQ 安装目录下,您应该找到一个名为Tools\c\Samples\mqccred 的子目录,这应该有32 位(lib)和64 位(lib64)的子目录。您应该将文件从lib 复制到exits 目录,从lib64 复制到exits64 目录。

    如果您使用的是托管 .NET 客户端模式,而您通过 props.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_CLIENT); 表明您没有使用该模式,您只需要一个本机 .NET 退出


    更新 2a 基于您的评论:

    抱歉,我使用的是MQC.TRANSPORT_MQSERIES_MANAGED。我从 其他线程。这是否意味着我需要编写 .NET 退出?

    mqcred 不适用于托管模式 .NET,要使用出口提供您在 .net 中编写等效项所需的凭据。

    通过属性在程序中指定凭据比编写类似于 mqcred 的托管模式退出要简单得多。

    Roger 对“Sending message on IBM MQ: Hangs on AccessQueue ”的回答提供了一个很好的示例,演示了在托管模式下传递用户名和密码。您仍然可以从 CCDT 获取连接详细信息。

            if (inParms.ContainsKey("-u"))
               qMgrProp.Add(MQC.USER_ID_PROPERTY, ((System.String)inParms["-u"]));
    
            if (inParms.ContainsKey("-x"))
               qMgrProp.Add(MQC.PASSWORD_PROPERTY, ((System.String)inParms["-x"]));
    
            if ( (inParms.ContainsKey("-u")) && (inParms.ContainsKey("-x")) )
               qMgrProp.Add(MQC.USE_MQCSP_AUTHENTICATION_PROPERTY, true);
    

    【讨论】:

    • 我认为,在添加更新 2 之前,我已修复了案例和 1415 个问题
    • @Pingpong 是否有任何进一步的信息可以为您提供帮助回答您的问题?我想根据你的问题,我已经提供了答案。如果不编写自己的 .NET 出口,您想要做的事情(仅使用 CCDT 提供来自托管 .NET 客户端的用户名和密码)是不可能的,但这并不意味着这个答案不正确。
    猜你喜欢
    • 2018-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-17
    • 1970-01-01
    • 1970-01-01
    • 2019-11-25
    相关资源
    最近更新 更多