本記事でやること
本記事ではApacheでOpenID Connect連携を行うモジュール(mod_auth_openidc)を利用して、Keycloakとリバプロ構成を検証する。
※本記事は、Keycloakのバージョンアップに伴い、Keycloakでリバプロ型構成を組んでみるの記事を最新化したものです。
mod_auth_openidcは、Apache用の認証・認可のモジュールであり、apacheに組み込むことでOpenID Connect Relying Party (RP)として、OpenID Connect Provider(OP)とID連携を可能にする。また、OAuth 2.0 Resource Serverとしても動作することができる。
Apache自体で動作するアプリケーション
Apacheがリバースプロキシしているアプリケーション
のどちらにおいても、コンテンツの保護および、ID連携を可能である。
Apacheの基本機能はそのまま利用可能なので、複数のリバースプロキシ先を指定したり、URL置換やヘッダ調整、アクセス制御などを組み合わせられるメリットがある。
OPとID連携を行ったユーザーIDはApacheのREMOTE_USER環境変数に連携されるようになり、その他のユーザー情報に関しては、IDトークン内claimの中に含まれているものであればHTTPヘッダから取得することが可能である。
今回は、WSLのUbuntu上でApache2とmod_auth_openidcを利用して、OP(Keycloakサーバー)とID連携の動作確認を行う。
動作環境・構成
対象 | FQDN | OS | 構成 |
---|---|---|---|
リバースプロキシサーバ | apache.test.com | Ubuntu 20.04.6 LTS | Apache2 2.4.41 |
Keycloakサーバ | kc-host | Windows10 | Keycloak 21.1.2 |
Webアプリケーションサーバ | localhost | Windows10 | actix-web |
Keycloakサーバ側の設定
Keycloakは、こちらのセットアップとロール設定方法を参考にして、
以下のdemoレルムおよびユーザーが作成されていることを前提とする。
ユーザー | ロール |
---|---|
user001 | user |
admin001 | user,admin |
クライアント追加・設定
1.Keycloakの管理コンソールにログインする。
2.左メニューバーからdemoレルム
を選択する。
3.左メニューバーでクライアント
をクリックすると、クライアント一覧が表示される。
4.一覧の上にあるCreate Client
ボタンを押下する。
5.各画面で以下のようなクライアント設定値を入力し、保存
ボタンを押下する。
・Client Type:OpenID Connect
・クライアントID:mod-auth-openidc-test
・ルートURL:http://apache.test.com
・有効なリダイレクトURI:http://apache.test.com/redirect_uri
・Webオリジン:http://apache.test.com
mod_auth_openidcを使う場合、有効なリダイレクトURIは、mod_auth_openidc側の設定のOIDCRedirectURIと同一のものを1つのみを設定する。
mod_auth_openidcでは、OIDCRedirectURIのURLを経由してユーザーが本来アクセスしていたURLに再度リダイレクトを行うため、1つのURLを許可するだけでよい。
6.クレデンシャル
タブを押下する。
7.mod_auth_openidcの設定で利用するため、クライアント・シークレット
として表示されている値を控える。
マッパー追加
上記の操作に引き続き、マッパーの設定を行う。
本設定によりIDトークンへ各ユーザーにアサインされているロールの値が追加され、mod_auth_openidc側で取得できるようになるため、後述のロールによるアクセス制御が可能となる。
- 作成したクライアントの
クライアント・スコープ
タブを押下する。
- スコープ一覧の
mod-auth-openidc-test-ded icated
のリンクを押下する。 -
Configure a new mapper
ボタンを押下する。
- 表示されるマッパータイプの一覧から
User Realm Role
を選択する。 - 以下のような設定値を入力し、保存 ボタンを押下する。
・Name:role
・マルチバリュー:オン
・トークンクレーム名:role
・IDトークンに追加:オン
・アクセストークンに追加:オン
・UserInfoに追加:オン
Webアプリ設定
特にKeycloakやmod_auth_openidcを意識することなく好きなようにWebアプリケーションをを作成する。今回はRustのWebフレームワークであるactix-webを利用して、以下の3画面があるWebアプリケーションを準備した。
画面名 | パス | 補足 |
---|---|---|
ホーム画面 | / | 認証不要でアクセス可能な画面 |
認証済専用画面 | /auth | Keycloakによる認証済ユーザーがアクセス可能な画面 |
管理者ロール専用画面 | /auth/role | adminロールを保持したユーザーのみがアクセス可能な画面 |
mod_auth_openidcの設定
Apache インストール
次のコマンドを実行してapacheをインストールする。
sudo apt install apache2
実行後、次のコマンドを実行してサービスを起動する。
sudo service apache2 start
サービス起動後、curl
等でhttp://localhost
へアクセスしてApacheのデフォルトページが表示されればインストール成功。
mod_proxyを有効化
今回apaheのプロキシ転送機能を利用するため、次のコマンドでmod_proxy
を有効化する。
sudo a2enmod proxy_http
/etc/apache2/sites-available/000-default.confの設定
設定ファイル全体
<VirtualHost *:80>
ServerName apache.test.com
ServerAdmin webmaster@apache.test.com
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
<Location />
ProxyPass http://webapp-host/
ProxyPassReverse http://webapp-host/
</Location>
<Location /auth>
AuthType openid-connect
Require valid-user
</Location>
<Location /auth/role>
AuthType openid-connect
Require claim "role~.*admin.*$"
</Location>
</VirtualHost>
以下の部分は、プロキシ転送として、/
のリクエストをすべてhttp://webapp-host/
へ転送する設定。
<Location />
ProxyPass http://webapp-host/
ProxyPassReverse http://webapp-host/
</Location>
以下の部分は、/auth
配下のパスへのアクセスをOIDC認証を必要とするよう設定。
<Location /auth>
AuthType openid-connect
Require valid-user
</Location>
以下の部分は、/auth/role
配下のパスへのアクセスをadmin
ロール保持が必要とするよう設定。
<Location /auth/role>
AuthType openid-connect
Require claim "role~.*admin.*$"
</Location>
mod_auth_openidcインストール
Ubuntu 20.04 ではOSで提供されているパッケージがあるため、次のコマンドでインストールする。
sudo apt install libapache2-mod-auth-openidc
/etc/apache2/mods-available/auth_openidc.confの設定
設定ファイル全体
OIDCRedirectURI http://apache.test.com/redirect_uri
OIDCCryptoPassphrase {任意のパスフレーズ}
OIDCProviderMetadataURL http://kc-host:8080/realms/demo/.well-known/openid-configuration
OIDCSSLValidateServer Off
OIDCResponseType "code"
OIDCClientID mod-auth-openidc-test
OIDCClientSecret {クライアント・シークレット}
OIDCCookiePath /auth/
OIDCRemoteUserClaim preferred_username
OIDCRedirectURI
リダイレクトURLを設定する。Keycloakで設定したものと同じ内容で設定する。
OIDCRedirectURI http://apache.test.com/redirect_uri
mod_auth_openidcで保護されているパス上のURLを指定する必要があるが、実際にコンテンツがあるURLを指定しないこと。このURLがOIDCの動作中に利用される予約URLとなり、ユーザーが直接呼び出すことができなくなるため。なお、直接呼び出した場合は、パラメーター不足で500エラーが発生する。
OIDCCryptoPassphrase
Cookieやキャッシュの暗号化で使用するパスフレーズ。任意の値を設定する。
OIDCCryptoPassphrase {任意のパスフレーズ}
OIDCProviderMetadataURL
OpenID Provider(OP)の.well-knownのURLを設定する。今回はKeycloakの.well-knownのURLを設定する。
http://kc-host:8080/realms/demo/.well-known/openid-configuration
OIDCSSLValidateServer
SSLを使用する場合に有効なサーバー証明書かどうかをチェックするかどうかを指定する。今回は検証用でチェック不要とするためOffにする。本番環境では、On(デフォルト)とすべき項目となる。
OIDCSSLValidateServer Off
OIDCResponseType
OpenID Connectのレスポンスタイプ設定する。今回は認可コードフローとしたいため、code
を設定する。
OIDCResponseType "code"
OIDCClientID
Keycloakで設定したクライアントのクライアントID(client-id)を設定する。
OIDCClientID mod-auth-openidc-test
OIDCClientSecret
Keycloak側で設定したクライアントのクライアント・シークレットを設定する。
OIDCClientSecret {クライアント・シークレット}
OIDCCookiePath
mod_auth_openidcで使用するCookieのパスを設定する。今回は認証を必要とするパスを/auth/
とするため、次のように設定する。
OIDCCookiePath /auth/
OIDCRemoteUserClaim
ApacheのREMOTE_USER環境変数に設定したいIDトークンのclaim名を指定する。今回はpreferred_username
を利用するため次のように設定する。
OIDCRemoteUserClaim preferred_username
設定反映
以下のコマンドを実行してOKで表示されれば、設定内容が正しいことを確認できる。
sudo apache2ctl configtest
以下のコマンドを実行して、サービスを再起動し、設定を反映する。
sudo service apache2 restart
動作検証
未ログインでアクセス
未ログイン状態でホーム画面(/
)へアクセスする。
以下のように特に認証等不要でアクセス可能なことが確認できる。
次に、画面上の認証済専用画面(/auth
)と管理者ロール専用画面('/auth/role')へアクセスする。
認証済ではないため、どちらの画面でも以下のようにKeycloakの認証画面へリダイレクトされ、画面が表示できないこと確認できる。
User001(admin権限なしユーザー)でアクセス
admin権限のないユーザーで認証して制限のかかっているページへアクセスする。
まず、以下のようにKeycloakの認証画面でID、PWを入力してuser001でログインする。
ログイン後、認証済専用画面(/auth
)へアクセスすると、以下のように認証が必要な画面を表示することができ、リバースプロキシを介して認証状態によるアクセス制御ができることが確認できた。
また、この状態で管理者ロール専用画面('/auth/role')へアクセスする。
今度はadminロールを保持していないため、401エラーの画面が表示される。これによりロールがない場合にアクセスが拒否されていることが確認できる。
admin001(admin権限保持ユーザー)でアクセス
最後に、admin001(admin権限ありユーザー)でロール制限されているページへアクセスする。
まず、以下のようにKeycloakの認証画面でID、PWを入力してadmin001でログインする。
ログイン後、管理者ロール専用画面('/auth/role')へアクセスすると、以下のように認証が必要な画面を表示することができ、リバースプロキシを介してロール保持によるアクセス制御ができることが確認できた。
最後に
今回、Ubuntu環境でmod_auth_openidcを利用して、KeycloakとOpenID ConnectでID連携させる方法が確認できた。
基本的なmod_auth_openidcの設定方法に関しては、Keyclaok公式ドキュメントに記載されている通りであり、あまりハマりポイントはなく設定することができた。
今回はリバースプロキシとして、mod_auth_openidcを検証したが、Keycloakの公式ドキュメントでは、Keycloakプロジェクトで開発されていたLouketo Proxy(旧Keycloak Gatekeeper)の代替OSSとしてOAuth2 Proxyの利用が推奨されているため、そちらもそのうち試してみたい。