既存の静的サイトに、後付けで以下のようなアクセス制限をかけたい。
site/
+- index.html : インデックスページ。ログインしていれば誰でも表示できる
+- user1/ : user1 用ディレクトリ。この中のファイルは user1 しか表示できない
| +- profile.html
+- user2/ : user2 用ディレクトリ。この中のファイルは user2 しか表示できない
+- profile.html
前回 は、Keycloak と zmartzone/mod_auth_openidc の組み合わせを試してダメだったので、今回は Apache2 の mod_auth_openidc
を試す。
前提
- OS: Windows 10 Pro
- Docker: Docker version 20.10.6, build 370c289
構築イメージ
+----------+
| Keycloak |
+----------+
↑ localhost:8080
+---------+
| Apache2 |
+---------+
↑ localhost:18080
+---------+
| Browser |
+---------+
Keycloak の準備
docker-compose.yaml の取得
Invoke-WebRequest -OutFile docker-compose.yaml -Uri https://raw.githubusercontent.com/keycloak/keycloak-containers/master/docker-compose-examples/keycloak-postgres.yml
とりあえず今回は管理者情報含めてこのまま使う。
Keycloak コンテナ起動
Realm 追加
http://localhost:8080
へ接続- ログイン
Username
:admin
Password
:Pa55w0rd
- 左上の
Master
にマウスオーバーしたときに表示されるAdd realm
を押下 Add realm
ページが表示されるので、必要事項を記入してCreate
ボタン押下Name
:MyApp
Enabled
:ON
OAuth クライアントの追加
Clients
->Create
ボタン押下Add Client
ページが表示されるので、必要事項を記入してSave
ボタン押下Client ID
:Apache2
Client Protocol
:openid-connect
Root URL
:http://localhost:18080
Apache2
の設定ページが表示されるため、必要な項目を更新してSave
ボタン押下Access Type
:confidential
Mappers
タブ ->Create
ボタン押下、必要事項を記入してSave
ボタン押下Name
:User Realm Role
Mapper Type
:User Realm Role
Token Claim Name
:role
Installation
タブ ->Format Option
をKeycloak OIDC JSON
に変更 -> 値を控える
ロール・グループ・ユーザーの設定
ロール作成
- ログイン済みユーザーのロールを追加
Roles
->Add Role
ボタン押下Add Role
ページが表示されるので、必要事項を記入してSave
ボタンを押下Role Name
:authorized
user1
のロールを追加Roles
->Add Role
ボタン押下Add Role
ページが表示されるので、必要事項を記入してSave
ボタンを押下Role Name
:user1
user2
のロールを追加Roles
->Add Role
ボタン押下Add Role
ページが表示されるので、必要事項を記入してSave
ボタンを押下Role Name
:user2
グループ作成
Groups
->New
ボタン押下Create group
ページが表示されるので、必要事項を記入してSave
ボタン押下Name
:authorized
Role Mapping
タブを開くAvailable Roles
を選択し、add selected>
ボタン押下。Assigned Roles
にauthorized
が追加されたことを確認
ユーザー作成
usre1
を追加Users
->Add user
ボタン押下Add user
ページが表示されるので、必要事項を記入してSave
ボタン押下username
:user1
Email
:user1@example.com
Credentials
タブを開き、パスワード設定を行いSet Password
ボタンを押下Password
,Password Confirmation
を入力Temporary
:OFF
へ変更
Role Mappings
タブを開き、ロール設定を行うAvailable Roles
からuser1
を選択し、Add selected>
ボタンを押下
Groups
タブを開き、グループ設定を行うAvailable Groups
からauthorized
を選択し、join
ボタンを押下
usre1
を追加Users
->Add user
ボタン押下Add user
ページが表示されるので、必要事項を記入してSave
ボタン押下username
:user2
Email
:user2@example.com
Credentials
タブを開き、パスワード設定を行いSet Password
ボタンを押下Password
,Password Confirmation
を入力Temporary
:OFF
へ変更
Role Mappings
タブを開き、ロール設定を行うAvailable Roles
からuser2
を選択し、Add selected>
ボタンを押下
Groups
タブを開き、グループ設定を行うAvailable Groups
からauthorized
を選択し、join
ボタンを押下
Apache2 の準備
Docker イメージ作成
httpd:2.4.48 をベースに、 mod_auth_openidc
をインストールした Docker イメージを作成する。
See: https://github.com/mikoto2000/docker-images/blob/master/httpd/Dockerfile
設定ファイル作成
httpd.conf
イメージ内のデフォルトの設定ファイルをコピー。
docker run -d --rm --name httpd mikoto2000/httpd:latest
docker cp httpd:/usr/local/apache2/conf/httpd.conf ./httpd.conf.original
docker kill httpd
コピーした http.conf.original
を基に、 httpd.conf
を作成する。 その差分を以下に示す。
httpd.conf の差分
> diff.exe -u .\httpd.conf.original .\httpd.conf
--- ".\\httpd.conf.original" 2021-05-26 09:23:52.000000000 +0900
+++ ".\\httpd.conf" 2021-06-21 01:10:11.138620400 +0900
@@ -49,7 +49,7 @@
# prevent Apache from glomming onto all bound IP addresses.
#
#Listen 12.34.56.78:80
-Listen 80
+Listen 18080
#
# Dynamic Shared Object (DSO) Support
@@ -139,10 +139,10 @@
LoadModule setenvif_module modules/mod_setenvif.so
LoadModule version_module modules/mod_version.so
#LoadModule remoteip_module modules/mod_remoteip.so
-#LoadModule proxy_module modules/mod_proxy.so
+LoadModule proxy_module modules/mod_proxy.so
#LoadModule proxy_connect_module modules/mod_proxy_connect.so
#LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
-#LoadModule proxy_http_module modules/mod_proxy_http.so
+LoadModule proxy_http_module modules/mod_proxy_http.so
#LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so
#LoadModule proxy_scgi_module modules/mod_proxy_scgi.so
#LoadModule proxy_uwsgi_module modules/mod_proxy_uwsgi.so
@@ -196,7 +196,9 @@
#LoadModule speling_module modules/mod_speling.so
#LoadModule userdir_module modules/mod_userdir.so
LoadModule alias_module modules/mod_alias.so
-#LoadModule rewrite_module modules/mod_rewrite.so
+LoadModule rewrite_module modules/mod_rewrite.so
+LoadModule auth_openidc_module /usr/lib/apache2/modules/mod_auth_openidc.so
+
<IfModule unixd_module>
#
@@ -549,3 +551,8 @@
SSLRandomSeed connect builtin
</IfModule>
+<IfModule auth_openidc_module>
+Include conf/extra/oidc.conf
+</IfModule>
+
+
oidc.conf
以下を参考に oidc でのアクセス制限設定を行う。
- https://github.com/openstandia/keycloak-dockerfiles/blob/master/reverse_proxy-based-arch-examples/kc-mod_auth_openidc-example/reverse_proxy/proxy.conf
oidc.conf
という名前で以下設定ファイルを保存。
oidc.conf
########################################################################################
#
# Common Settings
#
########################################################################################
# バーチャルホスト設定
NameVirtualHost *:18080
# keepAlive設定
KeepAlive On
# [mod_auth_openidc] OpenID Connectのレスポンスタイプ設定(code = Authorization Code Grant)
OIDCResponseType "code"
# [mod_auth_openidc] Cookieやキャッシュの暗号化で使用されるパスフレーズの設定
OIDCCryptoPassphrase OuY94OFtB+cF0n1mhjV5zg==
# [mod_auth_openidc] RP(mod_auth_openidc)のセッションクッキーが設定されるドメインの設定
OIDCCookieDomain localhost
# [mod_auth_openidc] OP(Keycloak)との通信時にSSLを使用する際の、有効なサーバー証明書チェック有無の設定
OIDCSSLValidateServer Off
# [mod_auth_openidc] OP(Keycloak)のメタデータURLの設定
OIDCProviderMetadataURL http://host.docker.internal:8080/auth/realms/MyApp/.well-known/openid-configuration
# [mod_auth_openidc] クレームの連携方法の設定
OIDCPassClaimsAs headers
# [mod_auth_openidc] クレームのプレフィックスの設定
#OIDCClaimPrefix ""
<VirtualHost *:18080>
ServerName localhost
RewriteEngine On
RewriteOptions inherit
OIDCScope "openid"
# [mod_auth_openidc] リダイレクトURIの設定
OIDCRedirectURI http://localhost:18080/oidc-redirect
# [mod_auth_openidc] OP(Keycloak)に設定されているクライアントIDの設定
OIDCClientID Apache2
# [mod_auth_openidc] OP(Keycloak)に設定されているクライアントIDに対応するクライアントsecretの設定
OIDCClientSecret 75700c2f-7b91-470a-8104-47a7f62c30d3
# 認証ロケーション設定(/)
# 一旦、"/"以降を全て認証対象とし、対象から外す場合は、以下に別途記載する。
# ログインしていれば誰でも表示できる
<Location />
AuthType openid-connect
Require claim "role:authorized"
</Location>
# リダイレクト URL の設定
<Location /oidc-redirect>
AuthType openid-connect
Require valid-user
</Location>
# 制限ロケーション設定(/user1/)
# roleにuser1が設定されているユーザのみがアクセス可能
<Location /user1/>
AuthType openid-connect
Require claim "role:user1"
</Location>
# 制限ロケーション設定(/user2/)
# roleにuser2が設定されているユーザのみがアクセス可能
<Location /user2/>
AuthType openid-connect
Require claim "role:user2"
</Location>
# favicon.ico対策
<Location /favicon.ico>
Require all granted
</Location>
</VirtualHost>
Apache2 起動
作成した設定ファイルを適切に配置して Docker コンテナを起動。
docker run -it --rm --name httpd `
-v "$(pwd)/site:/usr/local/apache2/htdocs" `
-v "$(pwd)/httpd.conf:/usr/local/apache2/conf/httpd.conf" `
-v "$(pwd)/oidc.conf:/usr/local/apache2/conf/extra/oidc.conf" `
-p "18080:18080" mikoto2000/httpd:latest
動作確認
http://localhost:18080/index.html
へアクセスすると、 Keycloak のログイン画面が表示される。
冒頭で説明した通りのアクセス制限ができていることを確認。
以上。
参考資料
- Keycloakで実用的なリバースプロキシ型構成を構築してみよう:Keycloak超入門(7)(3/4 ページ) - @IT
- zmartzone/mod_auth_openidc: OpenID Certified™ OpenID Connect Relying Party implementation for Apache HTTP Server 2.x
- Keycloakでリバプロ型構成を組んでみる(mod_auth_openidc編) - Qiita
- Apacheの組み込みモジュールの確認方法 - 楽しいだけで十分です
- httpd
- RewriteEngine On にならない場合は、mod_rewrite を有効にする - Qiita
- Keycloakでリバプロ型構成を組んでみる(mod_auth_openidc編) - Qiita
0 件のコメント:
コメントを投稿