隣のサイトへ認証を丸投げ〜認証を管理したくない〜

2026年01月14日 水曜日


【この記事を書いた人】
ヒラマツ

セキュリティ本部 セキュリティ情報統括室に所属 システム開発者。2000年問題で「2038年問題は定年で対応しなくていい!」とフラグを...。

「隣のサイトへ認証を丸投げ〜認証を管理したくない〜」のイメージ

認証をnginx用にちょっと弄れる機能〜認証だってrewriteしたい〜の続き記事です。

ngx_auth_mod開発者のヒラマツです。

ここでは認証管理を別サイトへ任せたい方に、ngx_auth_modの新機能の用途を解説します。

認証管理をしたくない(できない)理由には、以下のようなものがあります。

  • アカウント更新などの認証情報の管理作業の負荷がつらい。
  • LDAPなどの認証ソースにサーバから直接アクセスできないので、認証ソースを使いづらい。

そもそも、情報共有のためにサイトを作るのであって、認証管理がしたいわけではありません。

認証の管理が辛いイメージ

ngx_rewrite_authはサイトの外へもプロキシーできます。ですので、認証をngx_rewrite_authでプロキシーして、別サイトに認証処理をさせることができます。

別サイトの認証を流用してるイメージ

つまり、ngx_rewrite_authを通せば、(認証管理されている)別サイトに認証管理を委譲できるのです。
これなら、認証管理の負荷を減らして、サイト自体の管理に集中できそうです。

管理が楽なイメージ

BASIC認証と認証モジュールの違い

ngx_rewrite_authを通すことで、別サイトのBASIC認証を認証モジュール代わりに使える理由を説明します。

ngx_http_auth_request_moduleの仕様を見ると、認証判断は、認証モジュールもBASIC認証とほぼ同じ方法で処理しています。
ここだけ見るとnginxからBASIC認証サイトを直接利用できそうですが、実はnginxからの直接利用は問題があります。

それは、BASIC認証サイトは「コンテンツ」を扱うのに対し、認証モジュールはコンテンツではなく「認証結果」を扱うからです。この違いにより、例えば、HTTPキャッシュの識別に使うETagヘッダーの扱いが変わり、正しく動かない可能性があります。

認証モジュールとBASIC認証サイトの対象の違い

そのため、BASIC認証サイトを認証モジュール代わりに動作させるには、扱う対象をコンテンツから認証結果に変換する必要があります。
ngx_rewrite_authを通せば必要な処理が代行されて、以下の図のようにBASIC認証サイトから認証結果を抽出するので、nginxの認証ソースとして利用できるのです。

別サイトの認証を流用してる構成


設定手順の概略

以後はnginxでの具体的な設定を説明します。実際に使用する際に活用してください。

別サイトのBASIC認証を認証ソースにするためのngx_rewrite_authの設定例について、以下の順で説明します。

  1. ngx_rewrite_authの設定
  2. nginxで認証結果をキャッシュする
  3. 必要に応じた高度なキャッシュ設定

以下の構成を想定して説明します。

設定例が前提にしてる構成

利用する環境に合わせて、適宜読み替えてください。

1. ngx_rewrite_authの設定

構成図1

まずは、以下の設定例のように、流用したいサイトのURLやキャッシュ期間などの設定をします。

socket_type = "tcp"
socket_path = "127.0.0.1:9200"
cache_seconds = 15
neg_cache_seconds = 2
use_etag = true
auth_realm = "Outsourced Authentication"

username_re = '^[0-9A-Za-z_\-]+$'
auth_url = "https://other.example.com/"
#root_ca_files = [
#        "/var/cats/etc/ca-certs/My-Network-CA.cer",
#]

set_username = "$u" # $uには受け取ったアカウント名が設定される
set_password = "$p" # $pには受け取ったパスワードが設定される

各パラメータの概要は、以下の通りです。詳細は、ngx_rewrite_authドキュメントを参照してください。

パラメータ名 概要
socket_typesocket_path TCPソケットの127.0.0.1:9200で機能を提供
cache_seconds 認証成功時のキャッシュ期間(15秒)
neg_cache_seconds 認証失敗結果のキャッシュ期間(2秒)
use_etag ETagおよびIf-None-Matchヘッダーを使った検証を有効化(nginxがHTTPキャッシュの検証で利用)
auth_realm BASIC認証の認証領域名(“Outsourced Authentication”)
username_re 入力されたアカウント名が1文字以上かつ、英数字、-_だけで構成されているかをチェック
auth_url 認証を委譲するサイトのURL(https://other.example.com/)
root_ca_files 追加のCA証明書を指定(プライベートCAの証明書で利用する)
set_username リクエストから受け取ったアカウント名($u)をそのまま渡す
set_password リクエストから受け取ったパスワードをそのまま渡す

ngx_rewrite_authの起動は、ngx_auth_modの他のモジュールと同様でsystemdなどで行います。
具体的な起動方法についてはngx_auth_modの「はじめに」を参照してください。

2. nginxで認証結果をキャッシュする

構成図2

次は、nginxからngx_rewrite_authを利用する設定です。
まずは、キャッシュの必要性を簡単に説明します。

最近のブラウザは、画像などの埋め込みコンテンツの数だけ並列にダウンロードの処理をします。その結果、BASIC認証も画像の数だけ並列に実行されがちです。

ブラウザからの認証が並列で行われる図

同じ認証情報で何度も判定処理を行うのは無駄ですし、遅延の原因にもなります。認証を委譲するサイトに過剰な負荷がかかると、利用停止のリスクもあります。そこで、認証結果をnginx側でキャッシュし、無駄な認証処理を減らす必要があります。

認証結果をキャッシュしたときの処理改善の図

以下は、http://127.0.0.1:9200で動くngx_rewrite_authの認証結果をキャッシュしつつ、/private/のパスで認証するnginxの設定例です。

proxy_cache_path /var/cache/nginx/auth levels=2 keys_zone=zone_auth:1m max_size=1g inactive=1m;
proxy_temp_path  /var/cache/nginx_tmp;

...

server {
    ...

    location = /auth {
        auth_request off;
        proxy_intercept_errors off;
        proxy_cache zone_auth;
        proxy_cache_key $remote_user;
        proxy_cache_lock on;

        proxy_pass http://127.0.0.1:9200;
        proxy_http_version 1.1;
        proxy_cache_revalidate on;
        proxy_pass_request_body off;
        proxy_set_header Content-Length "";

        ...

        internal;
    }

    location /private/ {
        auth_request /auth;
        proxy_cache off;

        ...
    }

    ...
}

認証結果のキャッシュ設定(proxy_cache_pathproxy_cacheproxy_cache_keyなど)は、設定ミスすると不正な認証が通ってしまう可能性があります。
各項目の意味を理解した上で設定してください。

3. 必要に応じた高度なキャッシュ設定

コンテンツキャッシュを併用したいなどの、複雑なキャッシュ設定方法は以下の記事で詳しく解説しています。


設定例の説明は以上です。

隣のサイトを有効活用して、ぜひ楽な認証管理ライフを!

ヒラマツ

2026年01月14日 水曜日

セキュリティ本部 セキュリティ情報統括室に所属 システム開発者。2000年問題で「2038年問題は定年で対応しなくていい!」とフラグを...。

Related
関連記事