C# から IBM MQ にユーザー名とパスワードを付けて接続した途端、なぜか 2035(MQRC_NOT_AUTHORIZED)で弾かれる……。資格情報を外すとつながるのに理由がわからない。この記事では、実際にハマった「ユーザー名サフィックス @keyman が原因だったケース」を軸に、C#・.NET の IBM MQ Managed クライアントでの 2035 エラーの原因と解決手順を、現場目線で体系的に整理します。
C# から IBM MQ に資格情報付きで接続すると 2035 エラーになる症状
まずは問題の症状を整理します。次のような条件のときに 2035 エラーが発生します。
- C#(.NET)から IBM MQ クライアント(Managed モード)で接続している
- 接続プロパティに
MQC.USER_ID_PROPERTYとMQC.PASSWORD_PROPERTYを指定している - この状態だと 2035(MQRC_NOT_AUTHORIZED) で接続失敗
- ユーザー名・パスワード指定を外すと接続できる
2035 は IBM MQ で最もよく見るエラーと言ってもよく、「認証に失敗したとき」だけでなく「権限不足のとき」も同じコードが返るため、原因の切り分けに時間がかかりがちです。今回はさらに、Java からの移行という背景も重なり、ユーザー名の書式の違いが落とし穴になっていました。
結論:C# 側ユーザー名の「@keyman」サフィックスが原因だった
このケースの直接の原因はとてもシンプルです。
- Java 版のクライアントでは、ユーザー名の末尾に
@keymanというサフィックスを付けていた - .NET(C#)側に移行した際も、同じユーザー名(例:
appuser@keyman)をそのまま使用した - .NET の IBM MQ Managed クライアントでは、この書式が 無効なユーザー名として扱われ認証エラーとなった
- ユーザー名から
@keymanを外してappuserにしたところ、2035 エラーが解消した
つまり、C# クライアントではユーザー名を「素の ID(例:appuser)」に戻しただけで接続が成功しました。Java 側ではセキュリティ連携や認証モジュール側の都合でこのようなサフィックスが使えていたとしても、.NET クライアントでは別物として扱われる、というギャップが原因です。
最小構成の C# コード例(Managed クライアント)
C# の IBM MQ .NET(Managed モード)で資格情報付き接続をする際の最小構成は、次のようになります。ポイントは次の 3 つです。
TRANSPORT_MQSERIES_MANAGEDを指定して Managed モードにするUSER_ID_PROPERTYにはサフィックスやドメイン表記を付けず、素の ID を渡すUSE_MQCSP_AUTHENTICATION_PROPERTYをtrueにする
using IBM.WMQ;
using System.Collections;
public class MqClientSample
{
public void Connect()
{
string mq_hostName = "mq.example.local";
string mq_channel = "APP.SVRCONN";
int mq_port = 1414;
string mq_queueManager = "QM1";
string mq_userId = "appuser"; // 素のユーザーID
string mq_password = "P@ssw0rd"; // 実際は安全な保管・取得方法を使用
var props = new Hashtable
{
{ MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_MANAGED },
{ MQC.HOST_NAME_PROPERTY, mq_hostName },
{ MQC.CHANNEL_PROPERTY, mq_channel }, // SVRCONN チャネル
{ MQC.PORT_PROPERTY, mq_port },
{ MQC.USER_ID_PROPERTY, mq_userId }, // appuser (@keyman など付けない)
{ MQC.PASSWORD_PROPERTY, mq_password },
{ MQC.USE_MQCSP_AUTHENTICATION_PROPERTY, true }
};
using (var qmgr = new MQQueueManager(mq_queueManager, props))
{
// ここまで到達すれば接続成功
// キューのオープンや PUT/GET を続けて実装
}
}
}
まずはこのように、余計な装飾のないユーザー ID で接続してみることが重要です。もしこの状態で接続できるのであれば、サフィックスやドメイン表記、ID マッピングなど、アプリ側で足し算している要素が疑わしいと分かります。
Java では動いたのに C# では 2035 になる理由
「Java アプリでは appuser@keyman で問題なく動いていたのに、C# に移行したら 2035 エラーになった」という状況の裏側には、次のような違いが潜んでいることが多いです。
- Java クライアント側で独自の認証連携(JAAS、カスタム LoginModule など)を持っている
- アプリケーションサーバ(WebSphere Application Server など)のユーザー管理が「
user@realm形式」に対応している - MQ サーバ側で CHLAUTH や MCAUSER のマッピングを使い、「
appuser@keyman→appuser」のような変換をしている
これらの仕組みが Java 環境の中でうまく調和していた場合、アプリケーションコードから見ると「appuser@keyman を渡せばよい」というノウハウだけが残ります。しかし .NET の IBM MQ クライアントは別実装であり、同じ書式のユーザー名を認識できるとは限りません。
移行時に一度「素の OS ユーザー名」に戻してテストすることは、こうしたレイヤー間の違いを炙り出す簡単かつ確実な方法です。
2035(MQRC_NOT_AUTHORIZED)の意味と考え方
2035 エラーは、IBM MQ の世界では「とりあえずこれを見たら認証か権限を疑え」と言われるほど頻出です。具体的には、以下のようなケースで返されます。
| 発生フェーズ | 主な原因 | 代表的な対処方針 |
|---|---|---|
| 接続(MQCONN/MQCONNX) | ユーザー名・パスワード誤り / ユーザーが存在しない / CHLAUTH でブロック | ユーザー名書式の見直し、CONNAUTH/CHLAUTH の確認 |
| キュー操作(MQOPEN/MQPUT/MQGET) | 対象キューへの権限不足(+put / +get などがない) | SETMQAUT で必要最小限の権限を付与 |
つまり、2035 が出たからといって「必ずパスワードが間違っている」とは限りません。今回のように「ユーザー名の形がおかしい」「CHLAUTH のマッチングで別ユーザーとして扱われている」といったパターンでも、同じく 2035 が返ってきます。
ユーザー名の書式:まずは「素」の ID で試す
C# の IBM MQ Managed クライアントでユーザー名を渡すときは、まず次のルールを守るのが安全です。
- 余計なサフィックスやドメイン表記を付けない(
appuser@keyman/DOMAIN\appuserは一度やめる) - OS に存在するローカルユーザー、あるいはディレクトリ(LDAP/AD)で定義された素の ID を渡す
- CONNAUTH で参照されるユーザーリポジトリと整合が取れているか確認する
| パターン | 例 | 最初の切り分け時の扱い |
|---|---|---|
| 素の ID | appuser | まずはこれで接続テスト |
| サフィックス付き | appuser@keyman | 2035 のときは一度外してテスト |
| ドメイン表記(バックスラッシュ) | DOMAIN\appuser | MQ サーバ側と方針を合わせるまで避ける |
| メールアドレス風 | [email protected] | 認証基盤が対応していない限り基本は非推奨 |
特に Java からの移行案件では、user@realm 形式の ID が「なんとなく当たり前」として浸透してしまっていることが多く、.NET クライアント側もそれに合わせてしまいがちです。2035 が解消しないときは、いったんこの前提を疑いましょう。
Queue Manager 側の権限設定(SETMQAUT)の基本
資格情報付きで接続できるようになったあと、キューを開こうとしたところで再び 2035 が出ることもよくあります。その場合は、ID/パスワードの認証は通っているものの、権限(オーソリティ)が不足している可能性が高いです。
IBM MQ では、管理者が SETMQAUT コマンドを使って、ユーザーごとにきめ細かく権限を付与します。典型的には次のようなイメージです。
SETMQAUT -m QM1 -t qmgr -p appuser +connect +inq
SETMQAUT -m QM1 -n QUEUE1 -t queue -p appuser +put +get +inq
SETMQAUT -m QM1 -n QUEUE1.DLQ -t queue -p appuser +put +inq
実運用では、次のような粒度で必要最小限の権限を付与するのが一般的です。
| 対象 | よく設定する権限 | 目的 |
|---|---|---|
| Queue Manager | +connect +inq | 接続と状態問い合わせ |
| 送信専用キュー | +put +inq | メッセージの送信と属性取得 |
| 受信専用キュー | +get +inq +browse | 受信・参照・属性取得 |
| DLQ(デッドレターキュー) | +put +inq | メッセージ退避のみ |
アプリ側から見ると、接続に失敗しているのか、接続後の操作で失敗しているのかで取るべき対策が変わります。ログや例外メッセージでどの API 呼び出し時に 2035 が返っているかを確認しましょう。
CHLAUTH / CONNAUTH の影響を理解する
IBM MQ では、チャネルレベルや接続レベルでのセキュリティ機構として CHLAUTH(チャネル認証)と CONNAUTH(接続認証)があります。これらの設定が、今回のような「資格情報なしだとつながるのに、ありだと 2035」という現象を引き起こすことも多いです。
CHLAUTH(チャネル認証)
CHLAUTH は、接続元 IP やチャネル名、ユーザー名などに応じて、接続を許可・拒否したり、別のユーザーにマッピングしたりする仕組みです。例えば、次のようなルールが設定されていることがあります。
- 特定 IP からの接続はすべて
mcauser('mqguest')に固定する - 匿名接続のみ許可し、資格情報付き接続(特定のユーザー名)は拒否する
この場合、「ユーザー名なしで接続 → mqguest にマッピングされて接続成功」「ユーザー名ありで接続 → CHLAUTH の別ルールに引っかかり 2035」という挙動になり得ます。
CONNAUTH(接続認証)
CONNAUTH が有効で CHCKCLNT(REQUIRED) などになっている場合、クライアントからの接続時には 必ずユーザー名・パスワード(MQCSP)がチェックされるようになります。
- ユーザー名がリポジトリに存在しない
- パスワードが誤っている
- 想定外の書式(今回の
@keyman付きなど)でユーザーが見つからない
といった状況では、CHLAUTH に到達する前の段階で認証エラーとなり、2035 が返されます。「サーバ側のセキュリティポリシーがどうなっているか」は、MQ 管理者に一度確認しておくと、切り分けがかなり楽になります。
「資格情報なしだと接続できる」場合の典型パターン
今回のように「資格情報を付けると 2035、外すと接続成功」という現象が起こるとき、現場でよく見かけるパターンをまとめると次のようになります。
| 現象 | サーバ側のよくある設定 | 対処の方向性 |
|---|---|---|
| ユーザー名なしだと接続成功 | SVRCONN チャネルに MCAUSER('mqguest') などが設定されている | ゲスト用ではなく、業務 ID での接続方針を整理する |
| ユーザー名ありだと 2035 | CHLAUTH で特定ユーザーをブロック / 期待と違うユーザーにマッピング | CHLAUTH ルールを洗い出し、想定ユーザーで接続できるよう調整 |
| Java では成功、C# では失敗 | Java 側でユーザー名マッピングや独自認証が組まれている | まずは素の ID で接続し、移行後の認証設計を作り直す |
「なぜ資格情報なしでつながるのか?」をきちんと理解しておかないと、いつの間にか全アプリがゲストユーザーで動いていた、という危険な運用にもつながりかねません。テスト段階であっても、できるだけ本番想定のユーザー ID で接続テストを行いましょう。
C# クライアント側の設定チェックポイント
ここまでのポイントを踏まえ、C# から IBM MQ に接続する際にチェックしておきたい項目を整理します。
| 項目 | 確認内容 | OK の状態 |
|---|---|---|
| ユーザー名 | サフィックスやドメイン表記を外したか(appuser など) | 素の ID で接続テスト済み |
| パスワード | 実際にログオン可能なパスワードを指定しているか | OS/AD で同じ ID/パスワードでログオンできる |
| MQCSP 利用 | USE_MQCSP_AUTHENTICATION_PROPERTY = true を指定しているか | MQCSP にユーザー名・パスワードが渡っている |
| チャネル | クライアント用の SVRCONN チャネル名を指定しているか | 管理者と合意したチャネル名になっている |
| ホスト / ポート | 接続先が正しい Queue Manager を指しているか | 別クライアント(例:amqscnxc)でも接続確認済み |
| TLS | TLS 環境の場合 CipherSpec や証明書配置は正しいか | サーバ側の CipherSpec と一致し、ハンドシェイクに成功する |
アプリ側の設定が整理できたら、次は MQ サーバ側(Queue Manager 側)のログと設定を見ていきます。
サーバ側ログ(AMQERR01.LOG)で原因を特定する
2035 エラーの切り分けで一番効くのは、サーバ側のエラーログを確認することです。Queue Manager のエラーログ(通常は AMQERR01.LOG)には、次のような情報が出力されます。
- どのクライアントから(IP アドレス、チャネル名など)接続が来たか
- どのユーザーとして認識されたか(
principal 'appuser'など) - どのオブジェクト(Queue Manager / キュー)へのアクセスで 2035 になったか
- CHLAUTH のどのルールにヒットしたか
「こちらは appuser で接続しているつもりなのに、ログでは 'nobody' や 'mqguest' になっている」といった場合は、CHLAUTH またはチャネルの MCAUSER 設定でマッピングされている可能性が高いです。
逆に、ログ上でも principal 'appuser@keyman' のように見えている場合は、今回のようにサフィックス付きユーザー名がそのまま認証にかけられて失敗していると推測できます。
2035 エラー解消のための実務的トラブルシュート手順
ここからは、現場での切り分け作業を効率化するために、実務向けのトラブルシュート手順をステップ形式でまとめます。
- 素のユーザー ID で接続テストする
C# からの接続コードを最小構成にし、USER_ID_PROPERTYにappuserのような素の ID を設定して接続を試します。ここで接続できるようなら、Java 時代のサフィックスやドメイン表記が原因だった可能性が高いです。 - 別ツールで同じ資格情報をテストする
MQ のサンプルコマンドや、別の MQ クライアントツール(例:MQ Explorer やコマンドラインのamqscnxc)から、同じユーザー名・パスワードで接続してみます。ここで成功するかどうかで、アプリコード側の問題か、MQ サーバ側の設定問題かを切り分けできます。 - サーバ側ログを確認する
Queue Manager のエラーログ(AMQERR01.LOG)で、どのユーザーとして認識され、どの段階で 2035 になっているかを確認します。CHLAUTH によるマッピングやブロックがないかもセットで確認します。 - 権限(SETMQAUT)の付与状況を確認する
管理者にdspmqautなどで権限設定を確認してもらい、対象ユーザーに+connect +inqと、必要なキュー権限(+put/+get/+browse)が付いているかをチェックします。 - CHLAUTH / CONNAUTH のポリシーを確認する
CHLAUTH が有効な場合、どのルールが今回の接続にマッチするかを管理者と一緒に確認します。CONNAUTH が有効な場合は、どのユーザーリポジトリ(OS ローカル、LDAP、AD など)が参照されているかも重要です。 - TLS を利用している場合は証明書まわりも確認
CipherSpec の不一致や証明書 CN の不整合などがあると、接続エラーが別の形で出てくることがあります。2035 に限らず、TLS 環境ではネットワーク層のログもあわせて確認すると安心です。 - 再発防止として「接続仕様」をドキュメント化する
最後に、接続に使うユーザー名の書式(サフィックスなし)、CONNAUTH/CHLAUTH の前提、必要な権限一覧などを簡単にドキュメント化しておくと、後続の開発者が同じ 2035 でハマる確率を大きく減らせます。
再発防止のための「かんたんチェックリスト」
最後に、この記事で扱ったポイントをチェックリスト形式でまとめます。新規プロジェクトや移行作業のときは、この一覧をベースに確認しておくと安心です。
| チェック項目 | 内容 |
|---|---|
| ユーザー名のサフィックス・ドメインを外したか | @keyman や DOMAIN\user といった装飾を一度やめ、appuser のような素の ID で接続を試した |
| MQCSP 認証を有効にしているか | USE_MQCSP_AUTHENTICATION_PROPERTY = true を指定し、ユーザー名・パスワードを MQCSP 経由で渡している |
| SVRCONN チャネル・ホスト・ポートが正しいか | MQ 管理者と合意したクライアント用 SVRCONN チャネル、ホスト、ポートを指定している |
| Queue Manager 側の権限を確認したか | 対象ユーザーに Queue Manager / キューへの必要最小限の権限が SETMQAUT で付与されている |
| CHLAUTH / CONNAUTH の影響を確認したか | CHLAUTH ルールや CONNAUTH 設定により、想定外のユーザーにマッピングされていないか、あるいはブロックされていないかを確認した |
| サーバのエラーログを確認したか | AMQERR01.LOG で、どのユーザーとして認識され、どの操作で 2035 になっているかを確認した |
まとめ:まずは「ユーザー名をシンプルに」、それでもダメならサーバ設定へ
C# から IBM MQ に資格情報付きで接続した際の 2035(MQRC_NOT_AUTHORIZED)エラーは、原因がアプリ側にあるのか、サーバ側の設定にあるのかが分かりにくく、どうしても調査が長期化しがちです。
今回の事例のように、Java からの移行時に持ち込まれた @keyman などのサフィックスや、ドメイン表記つきのユーザー名が原因になっているケースは意外と多くあります。まずはユーザー名をシンプルにして接続を試し、それでも 2035 が解消しない場合は、CHLAUTH / CONNAUTH / 権限設定 / TLS など、Queue Manager 側のセキュリティ設定を順番に確認していくのが効率的です。
この記事で紹介した最小コード例とチェックリストをそのまま現場で使えば、同種の 2035 エラーの多くは短時間で解消・切り分けできるはずです。C# から IBM MQ を安心して利用できるよう、最初に一度しっかりと接続まわりの設計と検証を行っておくことをおすすめします。

コメント