🎉

KeycloakでのOpenID Connectお勉強メモ #1

2021/07/11に公開
2

はじめに

Keycloakを使ってOpenID Connectをお勉強したメモです。

お勉強の内容をざっくりいうと
ブラウザでアクセスしたらそのサイトの認証認可基盤のKeycloakでログインしてアクセスするところのフローを見てみる
です。

1. 環境

  • mac book pro 1台 で検証環境を構築します。

    • macOS Big Sur(11.3.1)
  • macOS上にDockerで ApacheKeycloak を立てます。

    • docker desktop(3.4.0)
      • engine(20.10.7)
      • docker-compose(1.29.2)
  • macOS上のHTTPをキャプチャするソフトで WireShark を使用します。

  • Apacheが稼働するDockerのHTTPをキャプチャするソフトで tcpdump を使用します。

  • 物理PCのmacOSで立ち上げたブラウザ(Chrome)が End-user となります。Keycloakが OP で、Apacheに libapach2-mod-auth-openidc を入れて RP として動作するようにします。

component

2. 環境構築する

まずは環境構築です。以下の手順でやります。

  • (1) macの hosts を書き換える
  • (2) docker-composeを実行する
  • (3) Keycloakのセットアップ
  • (4) mod-auth-openidcのセットアップ

(1) macのhostsを書き換える

/private/etcにある hosts ファイルに

127.0.0.1 test-oidc-rp
127.0.0.1 test-oidc-keycloak

を追記します。

##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting.  Do not change this entry.
##
127.0.0.1       localhost
255.255.255.255 broadcasthost
::1             localhost

...

# Added by gebo ->
127.0.0.1       test-oidc-rp
127.0.0.1       test-oidc-keycloak
# <- Added by gebo.

...物理環境を汚すの嫌だったんですけど、どうしてもこれだけはやらないとダメでした...

(2) docker-composeを実行する

コンテナを一つ一つ建てるのは面倒なのでdocker-composeで一気にやります。
GitHubにDockerファイルを置いておくのでそれを使います。

GitHub - test-oidc

ターミナルで test-oidcディレクトリ に移動して( test-oidc がカレントディレクトリである状態で)
以下のコマンドを実行します。

$ docker-compose build
$ docker-compose -p test_oidc up -d

うまくいくと以下のイメージとコンテナが作成されて起動します。

  • Images
    • test-oidc-rp-image
    • jboss/keycloak
  • Containers / Apps
    • test-oidc-rp
    • test-oidc-keycloak

(3) Keycloakのセットアップ

Keycloakの初期設定をします。

http://test-oidc-keycloak:8080/auth/
の AdministrationConsole からKeycloakにログインします。
Username / Password は admin / password です。

画面左の Clients① から Create② します。

Client ID に testClient Protocol に openid-connect を設定して Save します。

次に表示される画面(Testの Settings タブが選択されている画面)で

Access Type = confidential
Valid redirect URIs =
http://test-oidc-rp:8081/secure
http://test-oidc-rp:8081/loggedout.html
http://test-oidc-rp:8081/secure/setting/setting-content.html
(3つ設定します)

と設定して画面下にスクロールして Save します。

そのまま Credentialsタブ①Secret の値をコピーしてメモ帳などに控えておきます。(このあとmod-auth-openidcの設定ファイルに利用します)

次はテスト用ユーザーの作成です。
Users① から Add user② をクリックします。

Username = hoge
Email = hoge@gebogebo.com

と入力し、Save します。

Username,Emailは何でもいいです。

Credentialsタブ① からパスワードを設定します。
TemporaryはOFFにしときます。

以上でKeycloakの初期設定は完了です。

(4) mod-auth-openidcのセットアップ

ここからはrp側のコンテナに入っている mod-auth-openidc の初期設定を行います。

さきほどDLした test-oidcrp フォルダに auth_openidc.conf というファイルがありますんでエディタで開いて編集します。
OIDCClientSecret の値(下例では [Please-change-this-to-Secret] )にKeycloakのセットアップで控えておいた Secret を設定します。

OIDCProviderMetadataURL       http://test-oidc-keycloak:8080/auth/realms/master/.well-known/openid-configuration
OIDCClientID                  test
OIDCClientSecret              [Please-change-this-to-Secret]
OIDCResponseType              code
OIDCScope                     "openid"
OIDCSSLValidateServer         Off
OIDCProviderTokenEndpointAuth client_secret_basic

OIDCRedirectURI               http://test-oidc-rp:8081/secure
OIDCCryptoPassphrase          passphrase
OIDCPreservePost              On

OIDCSessionInactivityTimeout  300

<Location /secure>
   AuthType         openid-connect
   Require          valid-user
   LogLevel         debug
</Location>

auth_openidc.conf をコンテナに転送します。
auth_openidc.conf があるディレクトリがカレントの状態で
以下のコマンドを実行します。

$ docker cp auth_openidc.conf test-oidc-rp:/etc/apache2/mods-enabled

以上でmod-auth-openidcの初期設定は完了です。
設定を反映させるためにコンテナを再起動しときます。

restart

3. 動作確認する

動作確認してみましょう。

以下のURLからトップページを表示します。

http://test-oidc-rp:8081

1

Login with Keycloak からログイン画面に遷移します。
ログインのUsername / Password は (3)Keycloakのセットアップ で設定したものでログインします。

2

ログインに成功するとUsernameEmailが表示されます。

  • Return to top while logged in : ログインしたままトップページに戻ります。
  • Logout : ログアウトします。

こんな感じで動けばベリーグットです。

4. HTTP通信をキャプチャする

ひとまず動くことが確認できました。
これでOpenID Connectできた、ということなんですが何がなんだかわかりません。
内部でどのような事が起きているのか、この図でいうところの a) ,b) , c) のHTTP通信をキャプチャします。

component

a),b) End-userとRP、OPのHTTP通信をキャプチャする

macOSで WireShark を立ち上げLoopbackをキャプチャします。

capture1

c) RPとOP間のHTTP通信をキャプチャする

コンテナtest-oidc-rp上でtcpdumpを起動しキャプチャします。

Docker Desktop から test-oidc-rp コンテナに入ります。
画面のこの位置の CLI アイコンをクリックするとtest-oidc-rpに入ってターミナルが立ち上がります。

capture2

tcpdumpを起動してキャプチャ開始します。

  • Ctrl+Cでキャプチャ終了します
# tcpdump -w /var/tmp/tcpdump-rp.cap
  • キャプチャファイルをmac に転送するのは、mac側で以下のコマンドでいけます。
# コンテナIDを調べる
$ docker ps
# コンテナからファイルをコピーしてくる
$ docker cp <コンテナID>:/var/tmp/tcpdump-rp.cap .

キャプチャしたHTTP通信をフロー図にしました。


Flow_OIDC

ごちゃごちゃしてて発狂しそうです。

つづく

おつかれさまでした

SAML,OAuthよりさらにめんどくさい感じがもう...

Discussion

sbinsbin

こんにちは、とてもわかりやすいです。

ところでApache だと

<Location /secure>
   AuthType         openid-connect
   Require          valid-user
   LogLevel         debug
</Location>

皆さんこのように解説されていて、同じレルムに複数のクライアントを置けて便利なんですが、
グループ単位の認証例は見かけません。
やり方があるのでしょうか? Validate User Role extention を使わないとできないとか。

gebogebo

ありがとうございます!

グループ単位の認証例は見かけません。
やり方があるのでしょうか? Validate User Role extention を使わないとできないとか。

うーん、ちょっとわからないですねぇ。
mod-auth-openidc の詳細であればこちらですかねー。
https://github.com/zmartzone/mod_auth_openidc