[Nginx]特定の画面だけでクライアント認証する

Nginxを利用してWebアプリケーションを動かすとき、基本的には全てのページにクライアント認証をかけるんですが、特定の画面ではクライアント認証をOFFにする必要があったので、クライアント認証を行う画面をNginxconfファイルで設定する方法を調べてみました。

前提条件

Nginx:1.20.0

クライアント証明書は作成済みであるものとしてすすめます。

通常のクライアント認証

通常、Nginxでは下記のように「.confファイル」を設定して、クライアント認証を行います。

    server {
        listen 443 ssl;
        ssl_certificate ssl/cert.pem
        ssl_certificate_key ssl/private.pem;

        ssl_verify_client on;
        ssl_client_certificate ssl/cacert.pem;
        ...
    }

ssl_verify_clientonを設定するとクライアント認証が行われます。

ssl_verify_clientに設定できる値は下記の通りです。

  • on:クライアント認証を行う
  • off:クライアント認証を行わない
  • optional:クライアント証明書を要求し、CA証明書があればその証明書を検証する
  • optional_no_ca:クライアント証明書を要求するが、信頼できるCA証明書で署名されていることを必要としない

今回は、この設定の中の「optional」を使用して、画面によるクライアント認証の切り替えを行ってみたいと思います。

クライアント証明書を要求した結果は、「$ssl_client_verify」という変数に保存されます。

クライアント認証を画面に応じて切り替える

以下のように.confファイルを編集し、画面に応じてクライアント認証するかどうか切り替えます。

    server {
        listen 443 ssl;
        ssl_certificate ssl/cert.pem
        ssl_certificate_key ssl/private.pem;

        ssl_verify_client optional;
        ssl_client_certificate ssl/cacert.pem;

        # クライアント認証無しでも表示したい画面
        # とりあえずここでは画像ファイルとかをクライアント認証なしで表示できるようにしている
        location ~* \.(js|jpg|png|css|ico)$ {
            root /usr/share/nginx/html;
        }

        location / {
            if ($ssl_client_verify != SUCCESS) {
                # クライアント認証に失敗していたら403エラーページを返却する
                return 403;
            }
            try_files $uri $uri/ /index.php?$query_string /index.html;
        }
        ...
    }

まず、ssl_verify_clientoptionalを設定します。あとはlocationディレクティブを追加していき、クライアント認証が不要な画面などの情報を記載します。クライアント認証が必要なlocationディレクティブの設定部分にはif ($ssl_client_verify != SUCCESS)により、クライアント認証失敗時の処理を記載します。

ここでは、403エラーページを表示するように設定しています。

最後に

クライアント認証は行いたいが特定の画面などは認証したくない場合、今回の設定を使用することでクライアント認証を行わずに対象のlocationへアクセスすることができるようになります。どうしてもクライアント認証をoffにできない場合、今回のように部分的にクライアント認証を行わないという方法もありだと思います。

コメントする

メールアドレスが公開されることはありません。