Search code examples
node.jsibm-mq

What additional steps are required to resolve the MQRC_NOT_AUTHORIZED error


I am using IBMCloud's code engine and the IBM Code engine sample project.

I am experiencing an authorization issue when connecting to a remote IBM MQ server from my Node.js application running in a Docker container. Despite configuring the necessary environment variables and settings, the application fails with the error:

MQError: OPEN: MQCC = MQCC_FAILED [2] MQRC = MQRC_NOT_AUTHORIZED [2035]

Environment and Setup:

  • Node.js Version: 18
  • Docker Base Image for Build Stage: ubuntu:20.04
  • Docker Base Image for Runtime Stage: node:16-slim
  • IBM MQ Node.js Module: ibmmq
# Stage 1: Build
FROM ubuntu:20.04 as builder

ENV NODE_VERSION 18
ENV APP_DIR /usr/local/clientapp

WORKDIR ${APP_DIR}

RUN apt-get update \
    && apt-get install -y --no-install-recommends curl gcc g++ make git ca-certificates \
    && curl --silent -k --location https://deb.nodesource.com/setup_${NODE_VERSION}.x | bash - \
    && apt-get install -y nodejs \
    && npm install -g npm

COPY . ${APP_DIR}

# Install packages for the application
RUN npm install --only=prod \
    && apt-get autoremove -y curl make gcc g++ python3 git \
    && apt-get purge -y \
    && rm -rf /var/lib/apt/lists/* \
    && chmod a+rx ${APP_DIR}/*

# Stage 2: Runtime
FROM node:16-slim as clientAppImage

ENV APP_DIR /usr/local/clientapp
WORKDIR ${APP_DIR}

# Copy built application from the builder stage
COPY --from=builder ${APP_DIR}/ ${APP_DIR}

# Copy the MQ configuration files
COPY ccdt/FOO_BAR.TAB ${APP_DIR}/mqconfig/FOO_BAR.TAB

# Set environment variables for MQ
ENV MQCHLLIB=${APP_DIR}/mqconfig
ENV MQCHLTAB=FOO_BAR.tab
ENV CCDTURL=file://${APP_DIR}/mqconfig/FOO_BAR.tab

EXPOSE 8080
CMD npm start

Code Snippet for MQ Connection

// approutes.js
const inboundQueueName = "SOME.INBOUND.QUEUE";
let mqclientInbound = new MQClient(inboundQueueName);


// mqclient.js
constructor(queueName) {
        this[_HCONNKEY] = null;
        this[_HOBJKEY] = null;
        this._queueName = queueName;
    }

performConnection() {
    return new Promise((resolve, reject) => {
        this.buildCNO()
            .then((cno) => {
                debug_info("CNO Built");
                return mq.ConnxPromise(MQDetails.QMGR, cno);
            })
            .then((hconn) => {
                debug_info("Connected to MQ");
                this[_HCONNKEY] = hconn;
                return this.performOpen();
            })
            .then((hObj) => {
                debug_info("MQ Queue is open");
                this[_HOBJKEY] = hObj;
                resolve();
            })
            .catch((err) => {
                debug_warn("Error establishing connection to MQ");
                debug_warn(err);
                reject(err);
            });
    });
    debug_info("Establishing Connection to MQ");
}

performOpen() {
    let od = new mq.MQOD();
    od.ObjectName = this._queueName;
    od.ObjectType = MQC.MQOT_Q;

    let openOptions = MQC.MQOO_OUTPUT | MQC.MQOO_INPUT_AS_Q_DEF | MQC.MQOO_BROWSE;
    debug_info("Performing open", this[_HCONNKEY]);

    return mq.OpenPromise(this[_HCONNKEY], od, openOptions); //<--- FAILING HERE
}

Debugging Attempts

  • File Presence: Verified the .tab file is present in the container.
  • File Case Sensitivity: Ensured consistent casing for file names.
  • Code Debugging: Added additional logging to verify where the error occurs.
  • Client vs. Server: Confirmed that the setup only uses client connections and does not require local queue manager connections.

Despite these steps, the application still encounters the authorization error.

Request for Help:

  • Authorization: What additional steps are required to resolve the MQRC_NOT_AUTHORIZED error when connecting to a remote IBM MQ server?
  • Configuration: Are there any specific configurations or settings that need to be adjusted either in the Dockerfile or the application code to properly authorize the connection?

Any guidance or suggestions would be greatly appreciated. Thank you!


Solution

  • If you don't want to specify userid / password then you will need to switch off the following logic.

    let csp = new mq.MQCSP();
    csp.UserId = credentials.USER;
    csp.Password = credentials.PASSWORD;
    cno.SecurityParms = csp;