NGINX PlusでSAML認証をやってみた!
NGINX PlusがSAMLのSPとして設定できるようになったので試してみました。
みなさん こんにちは
東京エレクトロンデバイスでエンジニアしているあつふみです。
今回は、NGINX PlusをSAML認証のSP(Service Provider)として利用する方法についてご紹介します。
SAMLとは
SAMLとは、Security Assertion Markup Languageの頭文字を取ったもので「サムル」と読みます。
SAMLは、SSO(シングルサインオン)やID連携などで利用される認証情報の規格で、XMLをベースとしたマークアップ言語で書かれています。似たような規格としてOpenID Connectというものもあります。
本ブログで詳細には説明しませんが、SAMLもOpenID ConnectもSSOを実現でき、一般的に次のような用途の違いがあります。
- SAML:企業の社員が社内に存在する複数アプリケーションに対してSSOを実現
- OpenID Connect:一般的なユーザーがApple IDなどのアカウントを使ってECサイトやWebアプリケーションに対してSSOを実現
今回は、NGINX PlusでSAMLを実現する方法を書きますが、NGINX PlusでOpenID Connectを利用してOkta連携したブログもありますので、興味がある方はぜひ読んでみてください。
NGINX PlusのSAML対応について
NGINX Plus Release 29 (R29)からSAML2.0をサポートするようになりました。
SAMLの設定は、NGINXのJavaScriptフレームワーク(njs)を使って構築します。また、NGINX PlusはSAML SPとして機能し、SAML IdP(Identify Provider)と連携してSSOを実現します。
検証構成とSAML認証フロー
今回の構成図とSAML認証フローは次のとおりです。
NGINX PlusをSPとして利用します。IdPには、Azure Entra ID(旧Azure Active Directory)を利用しています。サーバーは普段私が検証で使っているものを利用しました。クライアントのリクエスト情報をコンテンツとして返してくれるサーバーです。
設定手順
全てを説明すると長くなりますので、ポイントを絞って説明します。
設定方法については、次の記事を参考にしています。
Microsoft Entra ID を使用した SAML SSO 用に NGINX Plus を構成する
Azure Entra IDの設定
クライアントの認証はAzure Entra IDが担います。Azure Entra IDにユーザーの登録やNGINX Plusと連携するための設定を作っていきます。
まずはAzure portalにログインし、エンタープライズアプリケーションを作成します。
そして、次の図のようにSAML構成に関わる基本的な設定を作成し、認証するユーザーの登録をします。作成時の情報は、NGINX Plusの設定に必要なので赤線の情報はメモなどに控えておきます。SAMLの証明書もダウンロードしておきます。
NGINX Plusの設定
次にNGINX Plusの設定をしていきます。
今回は、ubuntu 22.04にNGINX PlusがインストールされているAWSのEC2インスタンスを利用しました。
NGINXは、次の流れで設定していきます。
- NGINX JavaScript モジュール(njs)をインストール
- NGINX Plusインスタンスにログインし、次のコマンドを実行してnjsをインストールしておきます
sudo apt install nginx-plus-module-njs
- NGINX Plusインスタンスにログインし、次のコマンドを実行してnjsをインストールしておきます
- SAML 証明書から公開鍵を抽出
- IdP 署名検証用に Microsoft Entra IDからダウンロードした証明書から、公開鍵証明書を抽出します
以下のコマンドを参考に公開鍵を抽出し、/etc/nginx/conf.d 配下におきます
openssl x509 -in <証明書名>.cer -outform DER -out <証明書名>.der
openssl x509 -inform DER -in <証明書名>.der -pubkey -noout > <証明書名>.spki
mv <証明書名>.spki /etc/nginx/conf.d/<証明書名>.spki
- IdP 署名検証用に Microsoft Entra IDからダウンロードした証明書から、公開鍵証明書を抽出します
- HTTPS通信終端のための証明書・鍵の用意
- NGINX PlusでHTTPS通信を終端するための、証明書・鍵を用意します
こちらを参考にしてみてください
- NGINX PlusでHTTPS通信を終端するための、証明書・鍵を用意します
- 設定ファイルをGitHubのリポジトリからクローン
- NGINX PlusでSAMLをするためのconfigがGithubで公開されていますので、GitHubのリポジトリをクローンします
cd /etc/nginx/conf.d
git clone https://github.com/nginxinc/nginx-saml
cp -rdf nginx-saml/* /etc/nginx/conf.d/
- NGINX PlusでSAMLをするためのconfigがGithubで公開されていますので、GitHubのリポジトリをクローンします
- /etc/nginx/nginx.confの設定
- vim コマンド等でnginx.confに以下のディレクティブを追加します
load_module modules/ngx_http_js_module.so;
- 同様にnginx.confのhttpブロックに次のディレクテイブを追加します
variables_hash_max_size 2048;
variables_hash_bucket_size 128;
- vim コマンド等でnginx.confに以下のディレクティブを追加します
- /etc/nginx/frontend.confの設定
- 認証成功時にリクエストをどこに転送するか設定します
my_backendに、認証成功後に転送するupstream(サーバー)を指定します
upstream my_backend {
zone my_backend 64k;
server <ServerのIPアドレス>;
} - 次にServer ブロック内に以下のようにHTTPS通信を終端する設定をします
listen 443 ssl;
server_name <証明書のコモンネーム>;
ssl_certificate <証明書のパス>;
ssl_certificate_key <鍵のパス>;
- 認証成功時にリクエストをどこに転送するか設定します
- saml_sp_configuration.confを編集
- 以下の値を「Azure Entra IDの設定」で使用した値に書き換えていきます
- map $host $saml_sp_entity_id -> defaultの値を識別子 (エンティティ ID)に変更 (画像①)
- map $host $saml_sp_acs_url -> defaultの値を応答 URL (Assertion Consumer Service URL)に変更 (画像②)
- map $host $saml_sp_sign_authn -> defaultの値をfalseに変更
- map $host $saml_sp_want_signed_response -> defaultの値をfalseに変更
- map $host $saml_sp_want_encrypted_assertion -> defaultの値をtrueに変更
- map $host $saml_idp_entity_id -> defaultの値をMicrosoft Entra 識別子に変更 (画像④)
- map $host $saml_idp_sso_url -> defaultの値をログイン URLに変更 (画像③)
- map $host $saml_idp_verification_certificate -> defaultの値をSAML 証明書から抽出した公開鍵(.spki)のパスに変更
- map $host $saml_sp_slo_url -> defaultの値をログアウト URLに変更 (画像⑤)
※$saml_sp_slo_urlの設定はオプションです
- 各設定値については、こちらのstep2に記載されているVariable/Descriptionをご参照ください
- 以下の値を「Azure Entra IDの設定」で使用した値に書き換えていきます
- 設定したconfigをリロード
- 以下のコマンドでconfigを読み込みます
nginx -s reload
- 以下のコマンドでconfigを読み込みます
テストしてみる
設定が完了したので、アクセスしてみます。
ブラウザを立ち上げ、SAML SP(NGINX Plus)のログインURLを入力すると、リダイレクトが要求されてMicrosoft Entra IDの認証画面が表示されました。
Microsoft Entra IDに認証情報を入力すると、認証後にリダイレクトが要求されてNGINX Plusにアクセスすることができました。
そして、NGINX Plusが私のサーバーへリクエストを届けてくれることで、次のようなコンテンツが表示されました。
無事、NGINX PlusがSAML SPとして動作していることが分かります。
SAMLの検証というと少々手間がかかるイメージがあるかと思いますが、githubにテンプレートが用意されていることもあり、比較的簡単に検証することができました。
NGINX PlusはこのようにIdPと連携することで、認証プロキシとして利用することもできます。
興味がある方はぜひご連絡ください!