WordPress REST APIのApplication Passwordが401になるとき認証値とAuthorization headerを切り分ける

WordPressのApplication PasswordでREST APIへ接続して401になる場合、passwordの打ち間違いだけが原因とは限りません。

AIものさし編集部

まず結論:再発行の前に「認証情報が届いたか」を確かめる

WordPressのApplication PasswordでREST APIへ接続して401になる場合、passwordの打ち間違いだけが原因とは限りません。確認する層は、HTTPS、WordPress username、Application Passwordが使える設定か、HTTP Authorization headerがWeb serverを通過してPHP/WordPressへ届いたか、対象API routeが認証後のユーザー権限を許すかです。

Application PasswordはWordPress 5.6以降の機能で、特定のWordPressユーザーに紐づく、アプリごとに発行・失効できる資格情報です。REST APIなどのプログラム認証向けであり、wp-adminへログインする通常パスワードではありません。WordPress公式手順ではHTTPS上のBasic Authenticationでユーザー名とApplication Passwordを送ります。HTTPSでなければ認証情報が暗号化されずに送られるため、まずURLがHTTPSであることを確認してください。

401は「認証されていない」状態を示す代表的な応答です。403は認証後に要求操作の権限がないときに使われることがあります。ただしプラグイン、WAF、proxy、host独自の認証層が応答を書き換えることもあるため、status codeだけで原因を確定しないでください。WordPress RESTのJSON error code/message、応答header、server logを合わせて見ます。

認証と権限を混同しない

REST API requestは概ね「HTTP request → Authorization headerの到達 → Basic Auth credentialの検証 → WordPress user確定 → routeのpermission check」という順で進みます。401なら、WordPressが認証されていない利用者として扱ったのか、proxy/WAFが先に拒否したのかを分けます。認証成功後の403なら、ユーザーのcapabilityやrouteの権限条件を確認します。

Application Passwordを新しく作っても、次の問題は直りません。

  • requestが違うhostnameや別のWordPress環境へ向いている

  • Basic Authを作るusernameが、WordPressのログイン名と違う

  • proxyがAuthorization headerを削除または転送していない

  • siteまたはuser設定でApplication Passwordが無効

  • routeが必要とするcapabilityをそのユーザーが持っていない

  • requestがredirect先へ移り、認証情報を想定どおり送信できていない

まず失敗requestの正確なURL、HTTP method、route、status、REST error codeを、secretを含めずに記録します。URL queryにもtokenやpasswordを含めないでください。

Application Passwordを使える状態か確認する

WordPress管理画面のUsers → Profile / Edit UserにApplication Passwordsの欄があるか確認します。Application Passwords機能は標準でも、サイト側のfilterやsecurity plugin、host設定、ユーザー設定によって利用不可の場合があります。設定画面に欄がない、作成ボタンがない、APIから利用できない場合は、値を何度も再発行する前にsite側の利用可否を確認します。

生成済みApplication Passwordは作成時に一度だけ表示される資格情報です。漏えいした、誤った場所へ貼った、または使ったか分からなくなった場合は、その個別credentialを失効して新しいものを安全に保管します。ユーザーの通常パスワードをApplication Passwordの代わりに使わないでください。

WordPress usernameはメールアドレスや表示名とは限らず、login nameと一致する必要があります。ユーザー名・passwordの前後の空白、Basic Authのusername:password形式、passwordをコピーした際の欠落も確認します。WordPressではApplication Passwordの表示上の空白は読みやすさのための区切りで、入力時には空白を除いて使えます。シェルやclient側が文字を変更していないかは秘密値を表示せず検査します。

Authorization headerが届いているか切り分ける

Basic AuthenticationはHTTPのAuthorization headerで送られます。reverse proxy、CDN、WAF、FastCGI/PHP-FPM、Apache/Nginx設定やsecurity pluginがAuthorization headerを落とすと、WordPressはcredentialを受け取れず未認証として扱うことがあります。再発行を繰り返す前に、requestがどの経路を通り、headerが各層を通過しているかを管理者に確認します。

秘密値を出さずにREST APIの認証経路を試すには、サーバーが信頼できるHTTPS endpointで、ユーザーにread権限のある安全なGET routeを選びます。例えばWordPress REST APIのcurrent-user endpointを検討できます。curlでBasic Authを指定するときは、コマンドへpasswordを直接書かず、対話的なpassword promptを使い、response bodyやheaderにcredentialを保存しない方法を選びます。実サイトへ書き込み・削除するPOST/PATCH/DELETEをテストに使わないでください。

結果はstatus codeだけでなく、WordPress REST JSONのerror codeを確認します。未認証を示すerrorなら、username/credential/header forwarding/HTTPSの層へ戻ります。認証成功後に権限エラーになる場合は、特定routeに必要なcapabilityを確認し、不要に管理者権限を付与しないでください。public routeが200を返すことだけでは、Application Password認証の成功を証明しません。

redirect・HTTPS・hostを確認する

HTTP URLからHTTPSへ、またはapexからwwwへredirectされる構成では、clientのredirect handlingによってAuthorization headerが次requestへどう渡るかに注意します。別hostへ移動する場合は、credentialを不用意に転送しない安全動作が一般的です。最初から正規HTTPS URLを使い、redirectを経由しないrequestを診断します。

同じサイト名でもstaging、production、複数site、subdirectory installでREST APIのbase URLが異なることがあります。ブラウザで見ている管理画面と、request先のhostが同じ環境とは限りません。API URL、redirect chain、TLS証明書のhost、対象ユーザーが存在するsiteを照合します。Application Passwordを別サイトへコピーしても同じユーザーcredentialとして使えるとは限りません。

401から始める原因分岐

表は横にスクロールできます

観測確認する層次の一手
HTTPSでないtransport正規HTTPS endpointを使い、認証情報をHTTPで送らない
responseがredirectURL/hostredirect前の正規URLへ直接request
REST errorが未認証を示すcredential/headerusername・Application Password・Authorization forwarding
Application Password機能が見えないsite/user設定version、filter、plugin、host policyを確認
401が全routeで出る認証層Authorization header、basic auth対応、proxy logs
認証後に403permission checkmethod/routeのcapability、ユーザーrole
ある環境だけ失敗environment mismatchstaging/production hostname、secrets mapping
browserだけ失敗browser/proxyCORS、browser auth header送信、preflightを別診断

401と403の意味はWordPress coreの一般的なREST応答に沿った切り分けです。外部のproxyやpluginがstatusを変更している場合、表の対応だけでは断定できません。REST error codeとサーバーログを含めて調べます。

段階的な診断手順

  1. 安全なread-only routeを選ぶ。 request先siteで現在のユーザー情報などを安全に参照できるendpointを選びます。個人情報や投稿内容を返す場合は共有せず、bodyを保存しない設定にします。

  2. 正規HTTPS URLへ直接送る。 redirectを含まないAPI URLとhostを使用します。

  3. usernameを確認する。 WordPressのlogin nameであることを管理者に確認し、表示名・メールアドレスと混同しないようにします。

  4. Application Passwordの状態を確認する。 正しいsite/userに紐づく有効なcredentialか、必要なら個別に失効・再発行されたかを確認します。

  5. Basic Authを対話的に試す。 credentialをshell history、source、CI log、process list、Issueへ直接書かない方法を選びます。curl実行後にbodyやAuthorization headerを保存しません。

  6. REST responseを読む。 status、WordPress JSON error code、request host、redirect有無だけを記録します。credential、cookie、個人情報はredactします。

  7. header経路を確認する。 失敗が続く場合、proxy、WAF、web server、PHP-FPMの各層でAuthorization headerが転送されているかを管理者が確認します。ログにheader値を出さないでください。

  8. 認証と権限を分ける。 未認証ならcredential/header経路を調べ、認証後の権限不足ならrouteのpermission/capabilityを調べます。

  9. 必要最小限で再試験する。 まずGETで認証を確認し、書込みが必要ならstagingやテストデータで対象操作の権限を別に確認します。

  10. 不要credentialを失効する。 漏えい可能性がある個別Application Passwordだけをrevokeし、通常パスワードや関係のないcredentialは変更しません。

管理者・hosting担当へ伝える情報

header forwardingを調べてもらう場合、必要なのはrequest時刻、正規host、method、route、status、REST error code、利用しているweb server/proxyの構成です。Authorization headerの値やBase64文字列は送らず、「headerが上流へ存在するか」を値なしで確認してもらいます。

PHPやweb serverのログでheaderを記録する場合も、値をログへ出さず、存在するかどうかだけを一時的に判定します。Basic Auth値をBase64化しても暗号化ではないので、ログに残してはいけません。設定変更はまずstagingで試し、他の認証経路への影響を確認してから反映します。

再試験と終了条件

認証が成功したことを判断するには、正しいsiteへ送った安全なGETが、意図した利用者として認証されて応答したことを確かめます。public endpointの200だけでは証明にならないため、認証を要求するread-only routeを選び、必要なら応答内のユーザー識別情報を画面へ表示せず、ローカルで期待値と比較します。

次に実際の対象routeでmethodとcapabilityを分けて確認します。GETが成功してもPOST権限があるとは限りません。Application Passwordによる認証はユーザーの権限を越えるものではなく、そのユーザーが持つcapabilityでREST操作が判定されます。投稿作成や更新を試す場合、最初はstaging上のテスト投稿で行い、Productionへ不要なデータを作らないようにします。

修復完了の記録には、credentialを除いた次の情報を残します。

  • WordPressのversionとApplication Password機能の有効/無効

  • 正規HTTPS hostとREST route

  • request method、HTTP status、REST error code

  • Authorization headerが各proxy/server層を通過したか(Yes/No/Unknown)

  • 利用したusernameの確認結果(値そのものは記録しない)

  • 認証が成功したread-only検査と、route capabilityの結果

  • credentialを失効または再発行した場合は、対象アプリ名と日時のみ

次に行うこと

まず認証情報を再発行せず、失敗requestのhost・redirect・status・REST error codeを確認します。正規HTTPS hostへ安全なGETを対話的Basic Authで送り、response bodyとsecretを保存せずに認証が成立するか試します。未認証errorならusername、Application Passwordの有効状態、Authorization header forwardingを確認します。認証後に403なら対象routeに必要なcapabilityとユーザーroleを確認します。実サイトのversion、proxy、plugin、user権限、request結果は未確認なので、どの層が原因かはこの診断で確定してください。

Sources