2026年10月21日

2026年10月21日

Nginxのauth_requestで外部の認証サーバーに判定を任せる方法

Nginx の auth_request は、リクエストを処理する前に別の URL へ「サブリクエスト」を送り、その応答コードを見てアクセスを許可するかどうかを決める機能です。ログインの判定そのものは、アプリケーションや認証専用のサーバー(以下「認証サーバー」)に任せ、Nginx はその結果に従って通すか止めるかだけを行います。

この記事の設定は nginx.org の公式ドキュメント(ngx_http_auth_request_module)で2026年10月時点の内容を確認し、nginx 1.30 の検証環境で動作を確かめています。

仕組み

  1. 利用者が保護されたURL(例: /private/)にアクセスする。
  2. Nginx は、利用者のリクエストヘッダー(Cookie や Authorization など)を付けて、認証サーバーにサブリクエストを送る。
  3. 認証サーバーの応答コードで結果が決まる。
認証サーバーの応答 Nginx の動作
2xx(200・204 など) アクセスを許可し、本来のコンテンツを返す
401 401 で拒否する。認証サーバーの応答の WWW-Authenticate ヘッダーも利用者に渡す
403 403 で拒否する
それ以外 エラーとして扱う(500 が返る)

認証サーバーの応答本文は利用者には返りません。判定に使われるのは応答コードとヘッダーだけです。

手順1: モジュールが使えるか確認する

ngx_http_auth_request_module は、ソースからビルドする場合は既定で組み込まれず、--with-http_auth_request_module を付けてビルドする必要があります。nginx.org の公式パッケージや、多くのディストリビューションのパッケージには組み込まれています。次のコマンドで確認できます。

nginx -V 2>&1 | grep -o with-http_auth_request_module

with-http_auth_request_module と表示されれば使えます。何も表示されない場合は、組み込まれたパッケージに入れ替えるか、ビルドし直す必要があります。

手順2: 認証サーバーを用意する

認証サーバーは、リクエストを見て「許可なら 2xx、未ログインなら 401、権限不足なら 403」を返す HTTP のエンドポイントであれば、言語や製品は問いません。既存の Web アプリケーションのセッション確認用URL を使うこともできます。

この記事では、127.0.0.1:9000 の /auth で認証サーバーが動いている前提で説明します。

手順3: Nginx の設定を書く

server {
    listen 443 ssl;
    server_name example.com;
    root /var/www/example.com;

    # 保護する範囲
    location /private/ {
        auth_request /_auth;

        # 認証サーバーが返したヘッダー X-Auth-User を変数に入れる
        auth_request_set $auth_user $upstream_http_x_auth_user;

        # 後ろのアプリケーションにユーザー名を渡す場合(proxy_pass を使うとき)
        # proxy_set_header X-Auth-User $auth_user;

        try_files $uri $uri/ =404;
    }

    # 認証サーバーへの問い合わせ用(外部からは開けない)
    location = /_auth {
        internal;
        proxy_pass              http://127.0.0.1:9000/auth;
        proxy_pass_request_body off;
        proxy_set_header        Content-Length "";
        proxy_set_header        X-Original-URI $request_uri;
        proxy_set_header        X-Original-Method $request_method;
    }
}
設定 意味
auth_request /_auth; このURIへのサブリクエストで許可を判定する
auth_request_set $変数 値; 判定が終わった後で変数に値を入れる。$upstream_http_ヘッダー名 で認証サーバーの応答ヘッダーを受け取れる
internal; このlocation を内部リクエスト専用にし、外部から直接開くと 404 にする
proxy_pass_request_body off; 利用者が送った本文(POSTのデータなど)を認証サーバーに送らない
proxy_set_header Content-Length ""; 本文を送らないので、Content-Length ヘッダーを外す
X-Original-URI など 元のリクエストのURIやメソッドを認証サーバーに伝える(ヘッダー名は認証サーバーに合わせる)

auth_request と auth_request_set は http・server・location に書けます。保護を外したい場所では auth_request off; を書きます。

手順4: 反映して動作を確かめる

sudo nginx -t
sudo systemctl reload nginx

curl で応答コードを見ます。下の例は、認証サーバーが X-Api-Key ヘッダーの値で判定する場合です。

# 認証情報なし → 認証サーバーが 401 を返すので 401
curl -s -o /dev/null -w '%{http_code}\n' https://example.com/private/

# 正しい認証情報 → 200
curl -s -o /dev/null -w '%{http_code}\n' -H 'X-Api-Key: test-key' https://example.com/private/

# 問い合わせ用のURLを直接開く → internal なので 404
curl -s -o /dev/null -w '%{http_code}\n' https://example.com/_auth

動作確認用の仮の認証サーバー

認証サーバーがまだ無い段階で設定を試すときは、Nginx 自身に仮の認証サーバーを作れます。X-Api-Key ヘッダーが test-key のときだけ許可し、X-Auth-User ヘッダーでユーザー名を返します。動作確認専用で、本番の認証には使わないでください。

server {
    listen 127.0.0.1:9000;

    location = /auth {
        if ($http_x_api_key = "test-key") {
            add_header X-Auth-User "alice" always;
            return 204;
        }
        return 401;
    }
}

検証環境ではこの組み合わせで、認証情報なしは 401、正しいヘッダー付きは 200、/_auth の直接アクセスは 404 になり、auth_request_set で受け取った変数にユーザー名が入ることを確認しました。

注意点

認証サーバーが止まると保護対象が開けなくなる

認証サーバーに接続できない、または 2xx・401・403 以外を返した場合はエラーになり、利用者には 500 が返ります。検証環境で認証サーバーを止めたところ、エラーログに auth request unexpected status: 502 と記録され、利用者には 500 が返りました。認証サーバーの監視と、エラーログ(/var/log/nginx/error.log)の確認方法を決めておいてください。

リクエストごとに問い合わせが発生する

既定では、保護対象へのリクエストのたびに認証サーバーへ問い合わせます。index によるディレクトリのインデックスや try_files の内部リダイレクトがあると、1回のアクセスで複数回問い合わせることもあります。負荷が問題になる場合は、/_auth の location で proxy_cache を使って判定結果をキャッシュできます(nginx 1.7.3 以降)。その場合は、キャッシュのキーに Cookie など利用者を区別する値を含めないと、ほかの利用者の判定結果が使い回されます。

認証サーバーとの通信を守る

認証サーバーを別のマシンに置く場合は、通信経路を HTTPS にするか、閉じたネットワークに置いてください。認証サーバーのURL を外部から直接開けないようにしておくことも必要です。

ほかのアクセス制限との組み合わせ

auth_request は、IPアドレスによる制限(allow・deny)や Basic認証(auth_basic)と satisfy ディレクティブで組み合わせられます。Basic認証そのものはNginxでBasic認証を設定する方法で説明しています。WordPress の管理画面や REST API を保護する例はNginx auth_requestで外部認証と連携する設定を参照してください。

まとめ

  • auth_request は、認証サーバーへのサブリクエストの応答コード(2xx・401・403)で許可を決める。
  • 問い合わせ用の location には internal、proxy_pass_request_body off、proxy_set_header Content-Length "" を書く。
  • 認証サーバーが返したヘッダーは auth_request_set と $upstream_http_* で受け取れる。
  • 認証サーバーが止まると 500 になるため、監視と問い合わせの負荷を考えて運用する。

お気軽にご相談ください

お見積りへ お問い合わせへ
▲