はじめに
ウェブサーバであるNginxと認証認可ツールKeycloakを連携させることで、アクセス時にユーザ認証をかけることが可能です。
本記事では実際にNginxとKeycloakを連携させ、アクセス時にログイン画面が表示される動きを確認しました。
環境情報
- keycloak-23.0.3
- nginx version: nginx/1.25.3
- Linux
事前準備(Nginx)
Nginxを準備した上でJavaScriptのモジュール(njs)をインストールします。
$ yum install nginx-plus-module-njs ... Installing: nginx-plus-module-njs x86_64 31+0.8.2-1.amzn2023.ngx nginx-plus 790 k Installing dependencies: libxslt x86_64 1.1.34-5.amzn2023.0.2 amazonlinux 241 k ... Complete!
続けてOpenID Connect関連のモジュール/設定ファイルをダウンロードした上で
$ git clone https://github.com/nginxinc/nginx-openid-connect
以下のファイル群から「frontend.conf openid_connect.js openid_connect.server_conf openid_connect_configuration.conf」を/etc/nginx/conf.d/配下にコピーします。
$ ls nginx-openid-connect/ LICENSE README.md configure.sh frontend.conf openid_connect.js openid_connect.server_conf openid_connect_configuration.conf
事前準備(Keycloak)
インストールしたKeycloakにadminユーザでログインをし、クライアントを作成します。ポイントとなる設定項目は以下。
- Cliend ID : NGINX-Plus
- Type : OpenID Connect
- Access settings/Valid redirect URIs : http://x.x.x.x:8010/_codexch
続いて準備したクライアントの中でロール(nginx-keycloak-role)を作成し、任意のユーザに同ロールをマッピングします。
注意点として「Role Mapping > Assign roles to xx」にて作成したロールを選択しますが、初期状態はレルムのロールしか表示されません。よって以下のようにクライアントロールでフィルターをします。
認証保護用の設定
KeycloakではOpenID Connectの設定を表示するエンドポイントがあるので、Keycloakが動作しているサーバに対してcurlコマンドを押下することで設定内容が確認できます。
# curl http://y.y.y.y:8080/realms/master/.well-known/openid-configuration | jq . ... { "issuer": "http://y.y.y.y:8080/realms/master", "authorization_endpoint": "http://y.y.y.y:8080/realms/master/protocol/openid-connect/auth", ...
この設定を/etc/nginx/conf.d/openid_connect_configuration.confに以下のように入れます。尚、oidc_client_secretに関してはKeycloakのコンソール上からクライアントの「Credentials」にて確認します。
map $host $oidc_authz_endpoint { default "http://y.y.y.y:8080/realms/master/protocol/openid-connect/auth"; } map $host $oidc_token_endpoint { default "http://y.y.y.y::8080/realms/master/protocol/openid-connect/token"; } map $host $oidc_jwt_keyfile { default "http://y.y.y.y::8080/realms/master/protocol/openid-connect/certs"; } map $host $oidc_client { default "NGINX-Plus"; } map $host $oidc_client_secret { default "XXX"; }
最後にfrontend.confを以下のように記載すれば設定は完了です。
location / { ... #auth_jwt_key_file $oidc_jwt_keyfile; # Enable when using filename auth_jwt_key_request http://y.y.y.y:8080/realms/master/protocol/openid-connect/certs; # Enable when using URL
動作確認
プロキシサーバとしてNginxへcurlを打つと以下のように302で画面遷移が行われます。
# curl http://x.x.x.x:8010 -v ... < HTTP/1.1 302 Moved Temporarily ... < Connection: keep-alive < WWW-Authenticate: Bearer realm="" < Set-Cookie: auth_redir=%2F; Path=/; SameSite=lax; < Set-Cookie: auth_nonce=xx; Path=/; SameSite=lax; < Location: http://y.y.y.y:8080/realms/master/protocol/openid-connect/auth?response_type=code&scope=openid&client_id=NGINX-Plus&redirect_uri=http://x.x.x.x:8010/_codexch&nonce=xx&state=0 < <html> <head><title>302 Found</title></head> <body> <center><h1>302 Found</h1></center> <hr><center>nginx/1.25.3</center> </body> </html> * Connection #0 to host x.x.x.x left intact
ブラウザで同URLにアクセスを行うと無事にKeycloakの表示されました。
終わりに
NginxとKeycloakの連携を実際に試してみました。本記事の流れはNGINX PlusのDeployment Guides「Set Up Single Sign-On for Proxied Applications>Single Sign-On with Keycloak」記載があるので、詳細はそちらをご参照ください。