こんにちは。サイオステクノロジーの木村です。
mod_auth_openidc は、Apache で OpenID Connect(OIDC)認証を実現するためのモジュールです。
mod_auth_openidc を用いたOIDC認証環境の構築手順について、OpenID Provider として Entra ID を利用する例で記載します。
検証環境
Rocky Linux 9.0
Apache 2.4.62
Entra ID の設定
アプリケーションの登録
1. Azure管理ポータルにサインインします。
2. サイドメニューより Microsoft Entra ID をクリックします。
3. 管理 – アプリの登録 をクリックし、表示された画面にて「+新規登録」をクリックします。
4. 以下の項目を入力し「登録」をクリックします。
・名前:任意の名称
・サポートされているアカウントの種類:シングル テナント
・リダイレクト URI :Web を選択し、リダイレクトURI(ユーザーが正常に認証またはサインアウトされた後に認証応答 (トークン) を返すときに宛先として受け入れられる URI)を入力
5. アプリが作成されます。「アプリケーション (クライアント)ID」をメモしておきます。
6. 画面上部の「エンドポイント」をクリックして表示された画面の「OpenID Connect メタデータ ドキュメント」をメモしておきます。
7. 管理 – 証明書とシークレット をクリックし、表示された画面にて「+新しいクライアントシークレット」をクリックします。
8. 任意の説明と期間を入力し、「追加」をクリックします。
9. 値をメモしておきます。
Apache HTTP サーバの構築と設定
インストール
1. Apache のインストールと確認
$ sudo dnf install -y httpd
$ httpd -v
2. mod_auth_openidc のインストールと確認
$ sudo dnf install -y epel-release
$ sudo dnf update -y
$ sudo dnf install -y mod_auth_openidc
$ sudo httpd -M | grep auth_openidc
auth_openidc_module (shared)
と表示されればモジュールがロードされています。
4. Apache の起動と自動起動設定
$ sudo systemctl start httpd
$ sudo systemctl enable httpd
HTTPSの設定
OpenID Connectでは、データのやり取りにHTTPS通信が必須となるため、ApacheでのHTTPS設定が必要です。
※ 今回は検証環境のため、自己署名証明書を使用した手順で行います。本番環境では信頼された認証局による正式な証明書をご使用ください。
1. mod_ssl のインストール
$ sudo dnf install -y mod_ssl
2. 自己署名証明書の作成
$ sudo openssl req -x509 -nodes -days 365 \
-newkey rsa:2048 \
-keyout /etc/pki/tls/private/example.key \
-out /etc/pki/tls/certs/example.crt
Common Name は、サーバのFQDNを入力します。それ以外は任意の値を入力します。
3. Apache の SSL設定
/etc/httpd/conf.d/ssl.conf
を編集して作成した証明書と鍵を指定します。
$ sudo vim /etc/httpd/conf.d/ssl.conf
<VirtualHost *:443>
ServerName [サーバのFQDN]
SSLEngine on
・・・(省略)・・・
SSLCertificateFile /etc/pki/tls/certs/example.crt
SSLCertificateKeyFile /etc/pki/tls/private/example.key
・・・(省略)・・・
</VirtualHost>
4. HTTP (ポート80) を無効化 or リダイレクト設定
必要に応じで設定を行います。(手順は割愛します)
5. ファイアウォール設定
Rocky Linux 9 では、デフォルトで firewalld が有効化されており、HTTPS が許可されていない場合、外部からのアクセスが制限されます。アクセス可能にするには以下のコマンドを実行します。
$ sudo firewall-cmd --permanent --add-service=https
$ sudo firewall-cmd --reload
OIDC認証の設定
1. /etc/httpd/conf.d/ssl.conf
を編集して、OIDC認証用の設定を追加します。
$ sudo vim /etc/httpd/conf.d/ssl.conf
<VirtualHost *:443>
・・・(省略)・・・
OIDCProviderMetadataURL [Entra ID の設定の手順でメモした OpenID Connect メタデータ ドキュメント]
OIDCClientID [Entra ID の設定の手順でメモした アプリケーション (クライアント)ID]
OIDCClientSecret [Entra ID の設定の手順でメモした クライアントシークレット]
OIDCPKCEMethod S256
OIDCResponseType code
OIDCScope "openid profile"
OIDCSessionInactivityTimeout 300
OIDCSSLValidateServer Off
OIDCProviderTokenEndpointAuth client_secret_post
OIDCRedirectURI [Entra ID の設定の手順で入力したリダイレクトURI]
OIDCCryptoPassphrase passphrase
OIDCRemoteUserClaim preferred_username
OIDCPassClaimsAs both
OIDCAuthRequestParams prompt=consent
<Location /secure>
AuthType openid-connect
Require valid-user
</Location>
・・・(省略)・・・
</VirtualHost>
OIDCSSLValidateServer
HTTPS で接続する際のサーバー証明書の検証方法 を制御する設定。今回は自己署名証明書を使用しているため Off(検証しない)にしていますが、通常は On に設定します。
OIDCCryptoPassphrase
セッション情報やトークン情報を暗号化する際に使用するパスフレーズ。任意の値を指定します。
OIDCRemoteUserClaim
認証後に Apache の REMOTE_USER 環境変数に格納するユーザー識別子(クレーム) を指定する設定。preferred_username を指定すると、IDトークンの preferred_username クレームの値が REMOTE_USER に設定されます。
OIDCPassClaimsAs
クレームをアプリケーション環境にどのようにして渡すかの設定。
environment (環境変数)、headers (HTTPヘッダー)、 both (両方)、 none(なし)
OIDCAuthRequestParams
認証リクエストを送信する際に追加のパラメータを指定するための設定。OIDCAuthRequestParams prompt=consent
とすると、同意画面が表示されます。同意画面を表示したくない場合は、prompt=consent
の指定は必要ありません。
2. 以下のコマンドで設定を確認します。
$ sudo apachectl configtest
Syntax OK
と表示されれば問題ありません。
認証後に表示するページの作成
今回はPHPで作成します。/var/www/html/secure/index.php
を以下の内容で作成します。
<?php
phpinfo();
?>
設定の反映
設定を反映するため Apache を再起動します。
$ sudo systemctl restart httpd
SELinux で Apache の外部通信を許可
Apache が外部通信できるように設定します。以下のコマンドを実行します。
$ sudo setsebool -P httpd_can_network_connect 1
以上で設定は完了です。
動作確認
OIDC認証できるか確認してみましょう。
1. ブラウザでhttp://[サーバFQDN]/secure/index.php
にアクセスします。
自己署名証明書のため警告画面が表示されますが、詳細を表示 – このWebサイトを閲覧 をクリックして継続します。
2. Entra ID のサインイン画面が表示されますので、Entra ID のユーザー情報を入力しサインインします。
3. 同意画面が表示されるので「承諾」をクリックします。
4. 認証後に表示するページの作成の手順で作成したPHPの設定を表示する画面が表示されます。
認証情報なども表示され確認できます。
参考
リクエストヘッダーで特定の情報のみ渡す方法
OIDCPassClaimsAs
を both または headersに設定すると、認証後に取得したユーザ情報のクレームが全てリクエストヘッダーとして受け渡されます。
全ての情報を受け渡すのではなく、特定のクレームのみ受け渡したい場合は以下のようにします。
<VirtualHost *:443>
・・・(省略)・・・
OIDCPassClaimsAs none
・・・(省略)・・・
<Location /secure>
# REMOTE_USER(preferred_username) と name のみヘッダに設定
RequestHeader set X-Remote-User "%{REMOTE_USER}s"
RequestHeader set X-Oidc-Name "%{OIDC-CLAIM-name}e"
</Location>
・・・(省略)・・・
</VirtualHost>
※ set の後に記載した名称で受け渡されます。