为MQ.NET客户端

时间:2018-04-21 17:25:39

标签: c# ibm-mq

通过.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是localhost address

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'。

  2. 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 Client 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(是)

    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。

2 个答案:

答案 0 :(得分:0)

  

队列管理器名称:LocalQM

糟糕的主意。你是在脚下射击自己。将UPPERCASE用于队列管理器名称和MQ对象名称。一旦您成为中级或高级MQAdmin,那么您可以尝试使用混合大小写的名称。

  

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

第1期:如果你没有在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支持。

答案 1 :(得分:0)

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

通过网络进行客户端连接有四个级别的CONNAUTH:

  1. CHCKCLNT(REQDADM)这是默认值。具有MQ管理权限的任何用户都必须提供有效密码。此外,任何没有提供密码的管理权限的用户都必须提供有效的密码。
  2. CHKCLNT(OPTIONAL)这类似于#1但不要求具有MQ管理权限的用户的密码。任何提供密码的用户管理员都必须提供有效密码,使用此值不需要管理用户发送密码。
  3. CHCKCLNT(REQUIRED)此值表示所有用户都必须提供有效密码。
  4. CHCKCLNT(NONE)没有用户需要提供密码,即使他们确实提供了密码,也不会对其进行验证。
  5. 您可以将AUTHINFO对象上的整个队列管理器的此值设置为CONNAUTH上的QMGR值。如果您将其设置为REQADMINOPTIONAL,则可以通过CHLAUTH规则将其针对特定渠道提升为更严格的值,例如REQUIRED。你不能把它设置得更低。

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

    您可以选择一些选项来保持安全性:

    1. 您可以使用CLNTCONN上指定的客户端安全出口来传递mqcred等凭据。
    2. 您可以将客户端证书与TLS一起使用,并将其映射到SVRCONN上的MCAUSER。
    3. 根据您指定QMNAME(LocalQM)更新1 注意,因为名称MQ周围没有单引号将其折叠为大写并将其设置为LOCALQM

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

      根据您的更新2 进行注释(以下内容从已移至聊天的评论中收集):

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

      如果您使用Managed .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);