【入門】Keycloak + Docker で OIDC の SSO を設定

Keycloak

Keycloak とは、SSO (シングルサインオン) 、認証、ユーザー管理を提供する OSS です。

本記事は、SAML や OpenOID Connect (OIDC) を理解したけど、結局 SSO ってどうやって実装するの?という方のための入門記事です。

スポンサーリンク

初めに

SSO について学習する場合は、以下の順で学習することをおすすめします。

スポンサーリンク

Docker で Keycloak をインストール

今回は Docker を利用して Keycloak の使い方を説明します。

Docker って何?という方や、インストール方法、使い方については以下の記事で解説しています。

Keycloak の使い方

docker run -p 8080:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin quay.io/keycloak/keycloak:17.0.1 start-dev
  1. http://localhost:8080/admin にアクセスします。
  2. admin ユーザーでログインします。パスワードは「admin」です。
    (Docker run のオプションが -e KEYCLOAK_ADMIN_PASSWORD=admin の場合)

リモートホストでコンテナを起動した場合

ポートフォワーディングを利用して localhost でアクセスしてください。
(外部からドメインを利用してアクセスする場合は、HTTPS でアクセスする必要があります。)

ssh -NL 8080:localhost:8080 $REMOTE_HOST_IP

赤線部分は、リモートホストの IP アドレスに置き換えてください

レルムの作成

Keycloak のレルムとは、ユーザーや認証するアプリケーションの情報などを1つにまとめたテナント (グループ) です。
例えば、顧客ごとにレルムを分けることで管理を分離できます。

  1. ナビゲーションメニューの「Master」にマウスオーバーすると「Add realm」が表示されるので選択
  2. 「Name」に「myrealm」と入力
  3. 「Create」を押下
https://www.keycloak.org/getting-started/getting-started-docker

ユーザーの作成

  1. ナビゲーションメニューの「Users」を選択
  2. 右側にある「Add user」を選択
  3. 作成するユーザー情報を入力
    1. Username: 「myuser」
    2. First Name: 名前を入力
    3. Last Name: 苗字を入力
  4. 「Save」を選択
https://www.keycloak.org/getting-started/getting-started-docker

認証情報 (Credentials) を設定

  1. 「ユーザー」ページの上部タブにある「Credentials」を選択
  2. パスワードを入力し「Set Password」を選択
  3. (オプション) Temporary を OFF にすると、初回ログイン時にパスワードを再設定しなくて済みます

作成したユーザーでログイン

  1. http://localhost:8080/realms/myrealm/account にアクセス
  2. 右上の「Sign In」を選択
  3. 先ほど設定した myuser でログイン

ログインに成功すると、右上に苗字と名前が表示されます。
(サンプルどおりに入力した場合は Foo Bar)

クライアント (アプリ) を設定

  1. 左側のナビゲーションバーから「Clients」を選択
  2. 右側の「Create」を選択しクライアント (アプリ) を作成
  3. 以下のように情報を入力
    1. Client ID: myclient (アプリ名)
    2. Client Protocol: openid-connect (利用するプロトコル)
    3. Root URL: https://www.keycloak.org/app/ (Keycloak が用意したテスト用アプリ)
https://www.keycloak.org/getting-started/getting-started-docker

アプリに SSO でログイン

今回はサンプルアプリ (https://www.keycloak.org/app/) を利用します。

  1. https://www.keycloak.org/app/ にアクセス
  2. 「Save」を選択
  3. 「Sign in」を選択
  4. 先ほど myuser でログインした情報を利用して自動で SSO を行います
    1. SSO に成功すると「Hello, Foo Bar」と表示されます
  5. 「Sign out」を選択
    1. サンプルアプリからログアウトします
    2. http://localhost:8080/realms/myrealm/account/#/personal-info もログアウトします
      (ログアウトしない場合はスーパーリロードしてください)
  6. 「Sign in」を選択
  7. 今度はログイン画面が表示 (myuser はログアウトしているので、SSO できない)
  8. myuser でログインすると4と同じ画面が表示されます。

よって、以下のいずれかにログインすると、SSO によってもう片方ではログインが不要になることが確認できます。

HTTPS/TLS の設定

本番環境で利用する場合は、HTTPS を介して keycloak のエンドポイントを公開します。

本作業は以下の手順で行います。

  1. Let's Encrypt (Certbot) の HTTP-01 チャレンジのために、Web サーバーとして nginx を稼働
  2. Let's Encrypt (Certbot) の HTTP-01 チャレンジSSL/TLS 証明書を発行
  3. Keycloak で SSL/TLS 証明書を利用して、HTTPS でエンドポイントを公開

Let's Encrypt については、以下の記事で説明しています。

また、本作業には docker-compose を利用します。docker-compose については、以下の記事で説明しています。

Keycloak + HTTPS の設定

export DOMAIN=ドメイン名

ドメイン名は、ご自身のドメインに置き換えてください。

version: '3'
services:
  keycloak:
    image: quay.io/keycloak/keycloak:17.0.1
    container_name: keycloak
    ports:
      - "8443:8443"
    volumes:
      - cert:/etc/letsencrypt
    environment:
      KEYCLOAK_ADMIN: admin
      KEYCLOAK_ADMIN_PASSWORD: admin
      KC_HOSTNAME: $DOMAIN
      KC_HTTPS_CERTIFICATE_FILE: /etc/letsencrypt/live/$DOMAIN/fullchain.pem
      KC_HTTPS_CERTIFICATE_KEY_FILE: /etc/letsencrypt/live/$DOMAIN/privkey.pem
    entrypoint: ["/opt/keycloak/bin/kc.sh", "start"]
    user: "0:0" #cert ボリュームに root 権限が必要なため
    depends_on:
      - certbot

  certbot:
    image: certbot/certbot:v1.7.0
    container_name: certbot
    volumes:
      - cert:/etc/letsencrypt
      - html:/usr/share/nginx/html/
    entrypoint: ["certbot", "certonly", "-d $DOMAIN", "-m hoge@foo.bar", "--agree-tos","--webroot", "-w","/usr/share/nginx/html/"]
    depends_on:
      - nginx

  nginx:
    image: nginx:alpine
    restart: always
    container_name: nginx
    volumes:
      - cert:/etc/letsencrypt
      - html:/usr/share/nginx/html/
    ports:
      - "80:80"

volumes:
  html:
  cert:

hoge@foo.bar はご自身のメールアドレスに置き換えます。

下から2番目のログで「Profile prod activated.」が表示されていれば成功です。

ブラウザから https://$DOMAIN:8443/admin/ にアクセスし、以下の画面が表示されれば成功です。
(※ $DOMAIN は、ご自身のドメインに置き換えてください。)

Keycloak の設定方法は、localhost の時と同じです。(ココ参照)

データベースを設定

Keycloak のデータ保管にデータベースを利用します。

データベースのベンダーを指定するには、ビルド時のオプションが必要です。

The database vendor.
Possible values are: dev-file, dev-mem, mariadb, mssql, mysql, oracle, postgres

Env: KC_DB Build option

https://www.keycloak.org/server/db#_relevant_options

そのため、Dockerfile を利用してビルドしたイメージを作成し、docker-compose で各コンテナを起動します。

vim keycloak_Dockerfile
FROM quay.io/keycloak/keycloak:latest
ENV KC_DB=postgres
RUN /opt/keycloak/bin/kc.sh build
version: '3'                                                                                                                                             
services:
  keycloak:
    #image: quay.io/keycloak/keycloak:17.0.1
    build:
      context: ./
      dockerfile: keycloak_Dockerfile
    container_name: keycloak
    ports:
      - "8443:8443"
    volumes:
      - cert:/etc/letsencrypt
    environment:
      KEYCLOAK_ADMIN: admin
      KEYCLOAK_ADMIN_PASSWORD: $PASSWORD
      KC_HOSTNAME: $DOMAIN
      KC_HTTPS_CERTIFICATE_FILE: /etc/letsencrypt/live/$DOMAIN/fullchain.pem
      KC_HTTPS_CERTIFICATE_KEY_FILE: /etc/letsencrypt/live/$DOMAIN/privkey.pem
      KC_DB_USERNAME: keycloak
      KC_DB_PASSWORD: $PASSWORD
      #KC_DB_SCHEMA: public
      KC_DB_URL: jdbc:postgresql://postgres:5432/keycloak
    entrypoint: ["/opt/keycloak/bin/kc.sh", "start"]
    user: "0:0" #cert ボリュームに root 権限が必要なため
    depends_on:
      - certbot
      - postgres
       
  certbot:
    image: certbot/certbot:v1.7.0
    container_name: certbot
    volumes:
      - cert:/etc/letsencrypt
      - html:/usr/share/nginx/html/
    entrypoint: ["certbot", "certonly", "-d $DOMAIN", "-m hoge@foo.bar", "--agree-tos","--webroot", "-w","/usr/share/nginx/html/"]
    depends_on:
      - nginx
       
  nginx:
    image: nginx:alpine
    restart: always
    container_name: nginx
    volumes:
      - cert:/etc/letsencrypt
      - html:/usr/share/nginx/html/
    ports:
      - "80:80"
       
  postgres:
    image: postgres:13.0-alpine
    container_name: postgres
    restart: always
    environment:
      POSTGRES_DB: keycloak
      POSTGRES_USER: keycloak
      POSTGRES_PASSWORD: $PASSWORD
    volumes:
      - ./postgres_data:/var/lib/postgresql/data
       
volumes:
  html:
  cert: 
export DOMAIN=ドメイン名
export PASSWORD=admin

ドメイン名と好きなパスワードを設定してください。

docker-compose up --build

ブラウザから https://$DOMAIN:8443/admin/ にアクセスし、以下の画面が表示されれば成功です。
(※ $DOMAIN は、ご自身のドメインに置き換えてください。)

スポンサーリンク

SSO の IdP として利用

Keycloak を SSO の IdP として利用する方法を紹介します。

今回は、SSO を実現するプロトコルとして、次の2通り説明します。

SAML

SAML で ID フェデレーションを設定し、SSO を実現します。

SP に IdP を登録

サービスプロバイダー (SP) に、Keycloak を SAML ID プロバイダー (IdP) として登録するため、SAML メタデータドキュメントを取得します。

  1. [Realm Settings] を選択
  2. [SAML 2.0 Identity Provider Metadata] を[リンク先を別名で保存]

取得した IdP 側の SAML メタデータドキュメントを、サービスプロバイダ (SP) でインポートします。
(例:https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_roles_providers_create_saml.html)

IdP に SP をクライアントとして登録

SAML ID プロバイダー (IdP) に SP をクライアントとして登録します。

事前に SP 側の SAML メタデータドキュメントを用意しておきます。
(例: https://signin.aws.amazon.com/static/saml-metadata.xml の [リンク先を別名で保存] )

  1. [Clients] を選択
  2. [Create] を選択
  1. [Select file] を選択
  2. SAML メタデータドキュメントを Import
  3. [Save] を選択

[IDP Initiated SSO URL Name] に SSO を開始する URL の末尾を設定

IdP で SAML アサーションを設定

Mappers を利用して、SAML アサーションをマッピングします。

  1. [Clients] を選択
  2. [Mappers] タブを選択
  • [User Attribute] は ユーザーの属性キーを利用して属性値を設定
  • [SAML Attribute Name] は Attribute element の Name 属性を設定

※ [username] 属性値の属性キーは、認証した [ユーザー名] です。

SAML レスポンスに含まれる SAML アサーションは以下のようになります。(SAML レスポンスの解析方法はこちら)

<Attribute Name="https://aws.amazon.com/SAML/Attributes/RoleSessionName">
  <AttributeValue>ユーザー名</AttributeValue>
</Attribute>

属性キーと属性値の設定

自分で任意の属性キーと属性値を設定することも可能です。

  1. メニューの [Users] を選択
  2. 管理するユーザーを選択
  3. [Attributes] タブを選択
  4. [key] フィールドに属性キーを入力
  5. [value] フィールド属性値を入力
  6. [Add] を選択
  7. [Save] を選択

[User Attribute] に上記で設定した属性キーを利用できます

今回は RoleAttribute をこちらに従って設定しました。

SSO を開始

[IDP Initiated SSO URL Name] で設定した URL にアクセスし、SSO を開始します。

https://<Keycloak のドメイン>:8443/realms/myrealm/protocol/saml/clients/amazon-aws?RelayState=<ログイン後にリダイレクトするエンコードした URL>

OpenID Connect (OIDC)

ここでは、クライアントの [Access Type] に confidential を利用します。

[Access Type] の [confidential] と [public] の違いは以下のドキュメントをご覧ください。

Confidential and Public Applications
Describes the difference between confidential and public application types.

IdP のクライアントに SP を登録

IdP である Keycloak のクライアントに SP を登録します。
(SP の例: https://aws.amazon.com/jp/blogs/news/built-in-authentication-in-alb/)

  1. [Clients] を選択
  2. [Create] を選択

OIDC メタデータを import
もしくは以下の手順で手動入力

  1. [Client ID] を入力
  2. [Root URL] にログイン後にリダイレクトする URL を入力

クライアントの [Access Type] を confidential に設定

  1. タブの [Credentials] を選択
  2. [Secret] をメモ

SP に IdP を登録

  1. [Realm Settings] を選択
  2. [OpenID Endpoint Configuration] を選択

SP 側で [OpenID Endpoint Configuration] をインポート or 内容を見て手動で入力します。

[Client ID] と [Secret] は先ほど設定したものです。

関連記事

SSO (シングルサインオン) 入門シリーズのその他の記事は以下のとおりです。


参考ページ

Keycloak - Getting started - Docker
Keycloak is an open source identity and access management solution
スタートガイド Red Hat Single Sign-On 7.4 | Red Hat Customer Portal
本ガイドは、実稼働環境で使用する前に Red Hat Single Sign-On を使用して評価するのに役立ちます。これには、スタンドアロンモードで Red Hat Single Sign-On サーバーをインストールし、ユーザーおよびアプリケーションを管理するためのアカウントおよびレルムを作成し、JBoss EAP...