ラベル Keycloak の投稿を表示しています。 すべての投稿を表示
ラベル Keycloak の投稿を表示しています。 すべての投稿を表示

2025年5月3日土曜日

Keycloak の Admin UI の開発環境を整える

やりたいこと

Keycloak の Admin Console に上手く動かない箇所があった ので、自分で直すために環境づくりをする。

前提

  • Docker インストール済み
  • docker exec コマンドが使えること

開発環境の起動

今回はすべての作業をコンテナ上で行う。

必要に応じてバインドマウントするなり、ベアメタルで環境構築するなりしてください。

docker run -it --rm -p "8080:8080" -p "5174:5174" ubuntu:24.04

必要なパッケージのインストール

Keycloak のビルド・実行には Node.js と Java が必要なのでインストール。

その他、開発に必要なものとして curl, git, vim をインストールする。

いろいろ

apt update
DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends curl git vim

OpenJDK

apt install -y openjdk-17-jdk-headless

NodeJS & pnpm

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.2/install.sh | bash
\. "$HOME/.nvm/nvm.sh"
nvm install 22
npm install -g pnpm

Keycloak のクローン

cd ~/
git clone --depth 1 https://github.com/keycloak/keycloak.git

開発用サーバーを起動

フロントエンドの開発用サーバーを起動

別ターミナルで開発用サーバーを実行。

docker exec -it 72cc1a87a306 bash
cd ~/keycloak/js/apps/admin-ui/
pnpm install
pnpm dev

これだけでは動作確認ができないので、後述の「バックエンドの開発用サーバー」と連携させる必要がある。

バックエンドの開発用サーバーを起動

別ターミナルで開発用サーバーを実行。

docker exec -it 72cc1a87a306 bash
cd ~/keycloak/js/apps/keycloak-server/
pnpm start --admin-dev

これで、先ほど起動した admin-ui の開発サーバーといい感じに連携して、 admin-ui のソース更新を反映してくれるようになる。

ここまでの動作確認

ブラウザで http://localhost:8080 にアクセスすると、 Keycloak のログイン画面になる admin/admin でログインできる。

フロントエンドの修正

試しに Welcome to keycloak の文字列を変更してみる。

vim ~/keycloak/js/apps/admin-ui/src/dashboard/Dashboard.tsx

ファイルを開いたら、 t("welcomeTo", { realmDisplayInfo }) となっている箇所を "Customized!!!!!" に変更する。

変更が反映され、 Welcome to Keycloak と書かれていた場所が Customized!!!!! になっているのがわかる。

以上。

参考資料

2025年4月29日火曜日

Keycloak で SAML のクライアント証明書を設定する

やりたいこと

こんなことをしたときに、

こんなことがありました。

Bug: SAML Client Signing Certificate Not Stored via Admin Console (26.1.3) · keycloak/keycloak · Discussion #39232 にワークアラウンドが記載されていたので試す。

前提

Spring Boot で SAML 認証をする(署名無しバージョン) - mikoto2000 の日記 を実施済み。

やったこと

  1. myrealm の適切なユーザーにロール admin を割り当てる(今回は mikoto ユーザーに admin ロールを割り当てた)

  2. keycloak が起動しているコンテナに接続

    docker exec -it f29b1a6f3f70 bash
  3. kcadm.sh にパスを通す

    export PATH=$PATH:/opt/keycloak/bin/
  4. mikotomyrealm にログイン

    kcadm.sh config credentials --server http://localhost:8080 --realm master --user mikoto --password <PASSWORD>
  5. クライアント saml-sp の id を確認

    • JSON から頑張って探す
    • 今回は dafe91db-651f-4728-90f0-0faf2228fa38 だった
    kcadm.sh get clients --server http://localhost:8080 --realm myrealm
  6. saml-sp にクライアント証明書を設定

    • MIID...(略) の部分をクライアント証明書の文字列に置き換える
    kcadm.sh update clients/dafe91db-651f-4728-90f0-0faf2228fa38 --server http://localhost:8080 --realm myrealm -s 'attributes={"saml.signing.certificate": "MIID...(略)"}'
  7. 適用されたかの確認

    • saml.signing.certificate が更新されていれば OK.
    kcadm.sh get clients/dafe91db-651f-4728-90f0-0faf2228fa38 --server http://localhost:8080 --realm myrealm

動作確認

Keycloak の myrealm -> Clients -> saml-sp -> Keys -> Signing keys config -> Client signeture requiredOn にしても、 Spring Boot の SAML 認証が通るようになった。 OK.

2021年6月22日火曜日

Spring Boot と Keycloak でアクセス制御したい

やっていく。

Path 権限
/ ログインしている人なら誰でもログイン可能
/users/user1 user1 のみログイン可能
/users/user2 user2 のみログイン可能
  • / に、各ユーザー用ページへのリンクを表示
  • ログインできないユーザーのページリンクがあっても無駄なので、 自分のページリンクのみを表示したい

前提

構築イメージ

+----------+
| Keycloak |
+----------+
 ↑ localhost:8080
+-----------------------+
| SpringBootApplication |
+-----------------------+
 ↑ localhost:8081
+---------+
| Browser |
+---------+

OAuth クライアントの追加

  1. http://localhost:8080 へアクセスし、 admin でログイン
  2. Clients -> Create ボタン押下
  3. Add Client ページが表示されるので、必要事項を記入して Save ボタン押下
    • Client ID : spring-boot
    • Client Protocol : openid-connect
    • Root URL : http://localhost:8081
  4. spring-boot の設定ページが表示されるため、必要な項目を更新して Save ボタン押下

Spring Boot アプリケーション作成

プロジェクトのひな形作成

Spring Initializr でプロジェクトのひな形を作成する。

今回使うのは こちら

Keycloak の依存を追加

Securing Applications and Services Guide に従い、 keycloak-spring-boot-starterkeycloak-adapter-bom を追加する。

最終的な pom.xml は以下。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.1</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>dev.mikoto2000.study.springboot.keycloak</groupId>
    <artifactId>gettingstarted</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>gettingstarted</name>
    <description>Demo project for Spring Boot with Keycloak</description>
    <properties>
        <java.version>11</java.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.keycloak.bom</groupId>
                <artifactId>keycloak-adapter-bom</artifactId>
                <version>12.0.1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.keycloak</groupId>
            <artifactId>keycloak-spring-boot-starter</artifactId>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

application.properties の修正

# server port
server.port=8081

# Keycloak
keycloak.auth-server-url=http://localhost:8080/auth

# レルム名を設定する。
keycloak.realm=MyApp

# クライアントIDを設定する。
keycloak.resource=spring-boot
keycloak.public-client=true

# OpenID ConnectのIDトークン属性を設定。
keycloak.principal-attribute=preferred_username

# ディレクトリと、アクセス許可のロールを定義
keycloak.security-constraints[0].authRoles[0]=authorized
keycloak.security-constraints[0].securityCollections[0].patterns[0]=/
keycloak.security-constraints[1].authRoles[0]=user1
keycloak.security-constraints[1].securityCollections[0].patterns[0]=/users/user1
keycloak.security-constraints[2].authRoles[0]=user2
keycloak.security-constraints[2].securityCollections[0].patterns[0]=/users/user2

アプリケーション実装

コントローラーとテンプレートを作る。

コントローラー

package dev.mikoto2000.study.springboot.keycloak.gettingstarted;

import java.security.Principal;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

/**
 * AppController
 */
@Controller
public class AppController {
    @GetMapping(path = "/")
    public String index(Principal principal, Model model) {
        model.addAttribute("username", principal.getName());

        return "index";
    }

    @GetMapping(path = "/users/{name}")
    public String customers(@PathVariable("name") String name, Principal principal, Model model) {

        model.addAttribute("username", name);
        return "userpage";
    }
}

テンプレート

index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>index</title>
</head>
<body>
    <p th:text="'Hello, ' + ${username}"></p>

    <ul>
        <li><a th:href="'./users/' + ${username}" th:text="'./users/' + ${username}"></a></li>
    </ul>
</body>
</html>

userpage.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title th:text="${username} + '\'s page'"></title>
</head>
<body>
    <p th:text="'Hello, ' + ${username} + '!'"></p>
</body>
</html>

動作確認

.\mvnw.cmd spring-boot:run して http://localhost:8081 へアクセス。

user1user2 でログインして、別ユーザーのユーザーページが見れないことを確認。

今回の方法だと、存在しないユーザーが分かってしまうが今はとりあえずいいや…。

後は、ログアウトとかエラーページの整備もやらないとですね。

参考資料

2021年6月21日月曜日

Apache2 + mod_auth_openidc + Keycloak でディレクトリごとにアクセス制限をかけたい

既存の静的サイトに、後付けで以下のようなアクセス制限をかけたい。

site/
    +- index.html       : インデックスページ。ログインしていれば誰でも表示できる
    +- user1/           : user1 用ディレクトリ。この中のファイルは user1 しか表示できない
    |   +- profile.html
    +- user2/           : user2 用ディレクトリ。この中のファイルは user2 しか表示できない
        +- profile.html

前回 は、Keycloakzmartzone/mod_auth_openidc の組み合わせを試してダメだったので、今回は Apache2 の mod_auth_openidc を試す。

前提

構築イメージ

+----------+
| 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 コンテナ起動

docker compose up

Realm 追加

  1. http://localhost:8080 へ接続
  2. ログイン
    • Username : admin
    • Password : Pa55w0rd
  3. 左上の Master にマウスオーバーしたときに表示される Add realm を押下
  4. Add realm ページが表示されるので、必要事項を記入して Create ボタン押下
    • Name : MyApp
    • Enabled : ON

OAuth クライアントの追加

  1. Clients -> Create ボタン押下
  2. Add Client ページが表示されるので、必要事項を記入して Save ボタン押下
    • Client ID : Apache2
    • Client Protocol : openid-connect
    • Root URL : http://localhost:18080
  3. Apache2 の設定ページが表示されるため、必要な項目を更新して Save ボタン押下
    • Access Type : confidential
  4. Mappers タブ -> Create ボタン押下、必要事項を記入して Save ボタン押下
    • Name: User Realm Role
    • Mapper Type: User Realm Role
    • Token Claim Name: role
  5. Installation タブ -> Format OptionKeycloak OIDC JSON に変更 -> 値を控える

ロール・グループ・ユーザーの設定

ロール作成

  1. ログイン済みユーザーのロールを追加
    1. Roles -> Add Role ボタン押下
    2. Add Role ページが表示されるので、必要事項を記入して Save ボタンを押下
      • Role Name: authorized
  2. user1 のロールを追加
    1. Roles -> Add Role ボタン押下
    2. Add Role ページが表示されるので、必要事項を記入して Save ボタンを押下
      • Role Name: user1
  3. user2 のロールを追加
    1. Roles -> Add Role ボタン押下
    2. Add Role ページが表示されるので、必要事項を記入して Save ボタンを押下
      • Role Name: user2

グループ作成

  1. Groups -> New ボタン押下
  2. Create group ページが表示されるので、必要事項を記入して Save ボタン押下
    • Name: authorized
  3. Role Mapping タブを開く
    1. Available Roles を選択し、 add selected> ボタン押下。 Assigned Rolesauthorized が追加されたことを確認

ユーザー作成

  1. usre1 を追加
    1. Users -> Add user ボタン押下
    2. Add user ページが表示されるので、必要事項を記入して Save ボタン押下
      • username: user1
      • Email: user1@example.com
    3. Credentials タブを開き、パスワード設定を行い Set Password ボタンを押下
      • Password, Password Confirmation を入力
      • Temporary: OFF へ変更
    4. Role Mappings タブを開き、ロール設定を行う
      • Available Roles から user1 を選択し、 Add selected> ボタンを押下
    5. Groups タブを開き、グループ設定を行う
      • Available Groups から authorized を選択し、 join ボタンを押下
  2. usre1 を追加
    1. Users -> Add user ボタン押下
    2. Add user ページが表示されるので、必要事項を記入して Save ボタン押下
      • username: user2
      • Email: user2@example.com
    3. Credentials タブを開き、パスワード設定を行い Set Password ボタンを押下
      • Password, Password Confirmation を入力
      • Temporary: OFF へ変更
    4. Role Mappings タブを開き、ロール設定を行う
      • Available Roles から user2 を選択し、 Add selected> ボタンを押下
    5. 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 のログイン画面が表示される。

冒頭で説明した通りのアクセス制限ができていることを確認。

以上。

参考資料

2021年6月20日日曜日

oauth2-proxy で、静的サイトに後付けでアクセス制限をかけたい

既存の静的サイトに、後付けで以下のようなアクセス制限をかけたい。

site/
    +- index.html       : インデックスページ。誰でも表示できる
    +- user1/           : user1 用ディレクトリ。この中のファイルは user1 しか表示できない
    |   +- profile.html
    +- user2/           : user2 用ディレクトリ。この中のファイルは user2 しか表示できない
        +- profile.html

Keycloakoauth2-proxy/oauth2-proxy を組み合わせることで、そういったことができそうなので試した。

現状の oauth2-proxy では、パスごとのアクセス権限設定できず、 アップストリーム単位でのアクセス制限しかないようだ。

前述の目的は達成できないが、とりあえず使い方だけ記録しておく。

前提

構築イメージ

+----------+        +-------+
| Keycloak |        | NGINX |
+----------+        +-------+
 ↑ localhost:8080    ^ localhost:8000
+--------------+      |
| OAuth2 Proxy |------+
+--------------+
 ↑ 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 コンテナ起動

docker compose up

Realm 追加

  1. http://localhost:8080 へ接続
  2. ログイン
    • Username : admin
    • Password : Pa55w0rd
  3. 左上の Master にマウスオーバーしたときに表示される Add realm を押下
  4. Add realm ページが表示されるので、必要事項を記入して Create ボタン押下
    • Name : MyApp
    • Enabled : ON

OAuth クライアントの追加

  1. Clients -> Create ボタン押下
  2. Add Client ページが表示されるので、必要事項を記入して Save ボタン押下
    • Client ID : oauth2-proxy
    • Client Protocol : openid-connect
    • Root URL : http://localhost:18080
  3. Oauth2-proxy の設定ページが表示されるため、必要な項目を更新して Save ボタン押下
    • Access Type : confidential
  4. Mappers タブ -> Create ボタン押下、必要事項を記入して Save ボタン押下
    • Name: Group Membership
    • Mapper Type: Group Membership
    • Token Claim Name: groups
  5. Installation タブ -> Format OptionKeycloak OIDC JSON に変更 -> 値を控える

ロール・グループ・ユーザーの設定

ロール作成

  1. Roles -> Add Role ボタン押下
  2. Add Role ページが表示されるので、必要事項を記入して Save ボタンを押下
    • Role Name: authorized

グループ作成

  1. Groups -> New ボタン押下
  2. Create group ページが表示されるので、必要事項を記入して Save ボタン押下
    • Name: authorized
  3. Role Mapping タブを開く
    1. Available Roles を選択し、 add selected> ボタン押下。 Assigned Rolesauthorized が追加されたことを確認

ユーザー作成

  1. Users -> Add user ボタン押下
  2. Add user ページが表示されるので、必要事項を記入して Save ボタン押下
    • username: mikoto
    • Email: mikoto2000@gmail.com
  3. Credentials タブを開き、パスワード設定を行い Set Password ボタンを押下
    • Password, Password Confirmation を入力
    • Temporary: OFF へ変更
  4. Groups タブを開き、グループ設定を行う
    • Available Groups から authorized を選択し、 join ボタンを押下

NGINX 起動

docker run --name nginx --rm -v "$(pwd)/site:/usr/share/nginx/html" -p "8000:80" nginx

OAuth2 Proxy の準備

実行バイナリのダウンロード

oauth2-proxy V7.1.3 のリリースページ から、 oauth2-proxy-v7.1.3.windows-amd64.tar.gz をダウンロードし、展開する。

展開した oauth2-proxyoauth2-proxy.exe にリネーム。

$COOKIE_SECRET=$(docker run ruby ruby -rsecurerandom -e'puts SecureRandom.base64(16)')

oauth2-proxy 実行

$CLIENT_SECRET="f2c7ef6b-e955-4ed2-8843-72f0975956f5"
$KEYCLOAK_BASE_URL="http://localhost:8080/auth/realms/MyApp/protocol/openid-connect"
$OAUTH2_PROXY_ADDRESS="http://localhost:18080"
$NGINX_ADDRESS="http://localhost:8000"

./oauth2-proxy --provider="keycloak" `
--client-id="oauth2-proxy" `
--client-secret=${CLIENT_SECRET} `
--login-url="${KEYCLOAK_BASE_URL}/auth" `
--redeem-url="${KEYCLOAK_BASE_URL}/token" `
--profile-url="${KEYCLOAK_BASE_URL}/userinfo" `
--validate-url="${KEYCLOAK_BASE_URL}/userinfo" `
--http-address=${OAUTH2_PROXY_ADDRESS} `
--upstream=${NGINX_ADDRESS} `
--scope="openid" `
--redirect-url="http://localhost:18080/oauth2/callback" `
--email-domain="*" `
--cookie-secret=${COOKIE_SECRET} `
--allowed-group="/authorized"

動作確認

http://localhost:18080/index.html へアクセスすると、 Keycloak のログイン画面が表示される。

ログインすると、 http://localhost:18080/index.html で、 NGINX に配置した index.html が表示される。

以上。

参考資料

2021年2月26日金曜日

Eclipse Che のユーザー情報を引き継いだまま別ネームスペースへデプロイしたい

元 che の keycloak エクスポート → 新 che デプロイ → 新 che で keycloak インポート。という感じでできるようだ。

前提

  • OS: Windows 10 Pro
  • ランタイム: Docker Desktop の Kubernetes

環境準備

ソースの取得

mkdir che_tmp
cd che_tmp

$WORK_DIR=$(pwd)

git clone --depth 1 https://github.com/eclipse/che.git

cd che
$CHE_SOURCE=$(pwd)

helm のバージョンアップ

Chocolatey で管理しているので、アップグレードする。

choco upgrade kubernetes-helm

デプロイ環境準備

ingress デプロイ

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/cloud/deploy.yaml

pod の確認。

PS C:\Users\mikoto\project\tmp\che_tmp\che>  kubectl get pods --all-namespaces
NAMESPACE       NAME                                        READY   STATUS      RESTARTS   AGE
ingress-nginx   ingress-nginx-admission-create-fnssb        0/1     Completed   0          81s
ingress-nginx   ingress-nginx-admission-patch-nxmpv         0/1     Completed   0          81s
ingress-nginx   ingress-nginx-controller-7fc74cf778-txd7v   1/1     Running     0          81s
kube-system     coredns-f9fd979d6-bsn9l                     1/1     Running     8          36d
kube-system     coredns-f9fd979d6-dxd4n                     1/1     Running     8          36d
kube-system     etcd-docker-desktop                         1/1     Running     15         36d
kube-system     kube-apiserver-docker-desktop               1/1     Running     16         36d
kube-system     kube-controller-manager-docker-desktop      1/1     Running     8          36d
kube-system     kube-proxy-td79h                            1/1     Running     8          36d
kube-system     kube-scheduler-docker-desktop               1/1     Running     20         36d
kube-system     storage-provisioner                         1/1     Running     34         36d
kube-system     vpnkit-controller                           1/1     Running     8          36d

IP アドレスをメモ

TYPE が LoadBalancer の CLUSTER-IP をメモする。この場合は 10.111.81.251。 以降は $DOMAIN_IP にメモした IP を設定したこととして進める。

PS C:\Users\mikoto\project\tmp\che_tmp\che> kubectl get services --namespace ingress-nginx
NAME                                 TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx-controller             LoadBalancer   10.111.81.251   localhost     80:31411/TCP,443:32118/TCP   20m
ingress-nginx-controller-admission   ClusterIP      10.99.113.1     <none>        443/TCP                      20m
$DOMAIN_IP="10.111.81.251"
$DOMAIN="$(echo ${DOMAIN_IP} | sed -e "s/\./-/g").nip.io"

ループバックアドレスの設定

start-process -verb runas powershell -ArgumentList netsh,interface,ipv4,add,address,Loopback,$DOMAIN_IP

追加されたことを確認。

netsh interface ipv4 show address Loopback

che を namespace che でデプロイ

kubectl create namespace che
cd $CHE_SOURCE\deploy\kubernetes\helm\che
helm dependency update
helm upgrade --install che --namespace che --set global.cheWorkspacesNamespace="che" --set global.ingressDomain=${DOMAIN}.nip.io  --set global.multiuser=true ./

アプリの確認。

PS C:\Users\mikoto\project\tmp\che_tmp\che\deploy\kubernetes\helm\che> helm list -n che
NAME    NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION
che     che             1               2021-02-26 06:40:16.5220543 +0900 JST   deployed        che-0.1.0

pod の確認。

PS C:\Users\mikoto\project\tmp\che_tmp\che\deploy\kubernetes\helm\che> kubectl get pods -n che
NAME                                READY   STATUS    RESTARTS   AGE
che-6b7475579d-k4pj2                1/1     Running   0          3m17s
che-dashboard-649cb64655-jwtsc      1/1     Running   0          6m48s
devfile-registry-7f5f8fdf4d-fpmtw   1/1     Running   0          6m48s
keycloak-5b4ff5bd5d-zndb8           1/1     Running   0          3m20s
plugin-registry-558796b4bd-xt96b    1/1     Running   0          6m48s
postgres-55d7974489-zwkht           1/1     Running   0          3m20s

keycloak にアクセス

keycloak にアクセスして管理者設定・ユーザー追加を行う。

start http://keycloak-che.${DOMAIN}.nip.io

che にアクセス

start http://che-che.${DOMAIN}.nip.io

ログインできることを確認する。

ユーザー情報エクスポート

Kuberenetes の Keycloak コンテナへログインする。

PS C:\Users\mikoto\project\tmp\che_tmp\che\deploy\kubernetes\helm\che> kubectl get pods -n che
NAME                                READY   STATUS    RESTARTS   AGE
che-696449ffff-rlmt9                1/1     Running   0          38m
che-dashboard-649cb64655-jwtsc      1/1     Running   0          61m
devfile-registry-7f5f8fdf4d-fpmtw   1/1     Running   0          61m
keycloak-cccb6d4b8-6jz8f            1/1     Running   0          41s
plugin-registry-558796b4bd-xt96b    1/1     Running   0          61m
postgres-55d7974489-zwkht           1/1     Running   0          57m
PS C:\Users\mikoto\project\tmp\che_tmp\che\deploy\kubernetes\helm\che> kubectl exec -it -n che -it keycloak-cccb6d4b8-6jz8f -- /bin/bash

ユーザー情報エクスポート。

/opt/jboss/keycloak/bin/standalone.sh -Dkeycloak.migration.action=export -Dkeycloak.migration.provider=dir -Dkeycloak.migration.dir=/opt/jboss/keycloak-export -Dkeycloak.migration.usersExportStrategy=DIFFERENT_FILES -Dkeycloak.migration.usersPerFile=100 -Djboss.http.port=8888 -Djboss.https.port=9999 -Djboss.management.http.port=7777 -Djboss.management.https.port=7776

以下のような表示が出たら完了。

22:35:14,133 INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0025: Keycloak 6.0.1 (WildFly Core 8.0.0.Final) started in 11106ms - Started 617 of 880 services (563 services are lazy, passive or on-demand)

Ctrl+C で終了する。

エクスポートした情報をローカル PC へコピー

kubectl cp -n che keycloak-cccb6d4b8-6jz8f:keycloak-export ./keycloak-export

別 namespace にデプロイし、ユーザー情報をインポートする

ネームスペースを変更してデプロイする。

kubectl create namespace newnamespace
helm dependency update
helm upgrade --install che --namespace newnamespace --set global.cheWorkspacesNamespace="newnamespace" --set global.ingressDomain=${DOMAIN}.nip.io  --set global.multiuser=true ./

pod の確認。

PS C:\Users\mikoto\project\tmp\che_tmp\che\deploy\kubernetes\helm\che> kubectl get pods -n newnamespace
NAME                                READY   STATUS    RESTARTS   AGE
che-7b97c6cb46-f6zq7                1/1     Running   0          106s
che-dashboard-649cb64655-pc2sz      1/1     Running   0          106s
devfile-registry-7f5f8fdf4d-9qb4j   1/1     Running   0          106s
keycloak-74d657c877-dgnnc           1/1     Running   0          106s
plugin-registry-558796b4bd-z85zq    1/1     Running   0          106s
postgres-55d7974489-dw94p           1/1     Running   0          106s

ユーザー情報インポート

エクスポートした情報を Kuberenetes の Keycloak コンテナへコピーし、ログインする。

PS C:\Users\mikoto\project\tmp\che_tmp\che\deploy\kubernetes\helm\che> kubectl get pods -n newnamespace
NAME                                READY   STATUS    RESTARTS   AGE
che-7cb46784f7-hmz6v                1/1     Running   0          40m
che-dashboard-649cb64655-rvdpz      1/1     Running   0          40m
devfile-registry-7f5f8fdf4d-rpx8j   1/1     Running   0          40m
keycloak-74d657c877-b66gt           1/1     Running   0          40m
plugin-registry-558796b4bd-6k9nw    1/1     Running   0          40m
postgres-55d7974489-r268l           1/1     Running   0          40m
PS C:\Users\mikoto\project\tmp\che_tmp\che\deploy\kubernetes\helm\che> kubectl cp -n newnamespace ./keycloak-export keycloak-74d657c877-b66gt:./
PS C:\Users\mikoto\project\tmp\che_tmp\che\deploy\kubernetes\helm\che> kubectl exec -it -n newnamespace -it keycloak-74d657c877-b66gt -- /bin/bash

ユーザー情報インポート。

/opt/jboss/keycloak/bin/standalone.sh -Dkeycloak.migration.action=import -Dkeycloak.migration.provider=dir -Dkeycloak.migration.dir=/opt/jboss/keycloak-export -Dkeycloak.migration.usersExportStrategy=DIFFERENT_FILES -Dkeycloak.migration.usersPerFile=100 -Djboss.http.port=8888 -Djboss.https.port=9999 -Djboss.management.http.port=7777 -Djboss.management.https.port=7776 -Dkeycloak.migration.realmName=che

以下のような表示が出たら完了。

22:54:15,594 INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0025: Keycloak 6.0.1 (WildFly Core 8.0.0.Final) started in 13818ms - Started 617 of 880 services (563 services are lazy, passive or on-demand)

Ctrl+C で終了する。

keycloak にアクセス

keycloak にアクセスして管理者設定を行う。

start http://keycloak-newnamespace.${DOMAIN}.nip.io

この時点で、 che の namespace で作成したユーザーが登録されているはず。

che にアクセス

start http://che-newnamespace.${DOMAIN}.nip.io

ログインできることを確認する。

参考資料

2019年7月22日月曜日

Docker で Keycloak に入門する

Keycloak の Getting Started Guide をやっていく。

前提

  • OS: Windows 10 Pro
  • Docker: Docker version 18.09.2, build 6247962
    • 使用イメージ: debian:buster-slim
  • Keycloak: 6.0.1

事前準備

コンテナ起動

docker run -it --rm -p "80:80" -p "8080:8080" -p "9080:9080" debian:buster-slim
  • 80: アプリケーションサーバーポート
  • 8080: keycloak ポート
  • 9080: アプリケーションサーバー管理用ポート

必要なパッケージを取得

apt-get update
apt-get upgrade -y
mkdir -p /usr/share/man/man1
apt-get install -y curl openjdk-11-jdk

※ openjdk は、 headless だとサンプルアプリのデプロイでエラーが発生するため、今回は普通のものをインストールする。

keycloak の準備

keycloak のインストール

ダウンロード

curl -L https://downloads.jboss.org/keycloak/6.0.1/keycloak-6.0.1.tar.gz -O

配置

tar xf ./keycloak-6.0.1.tar.gz -C /opt

初期設定

初期ユーザー作成

ユーザー mikoto を追加。

root@dd4775da3619:/# /opt/keycloak-6.0.1/bin/add-user-keycloak.sh -u mikoto
Press ctrl-d (Unix) or ctrl-z (Windows) to exit
Password:
Added 'mikoto' to '/opt/keycloak-6.0.1/standalone/configuration/keycloak-add-user.json', restart server to load user

すでに keycloak サーバーを起動してしまっている場合は、サーバーを再起動するとユーザーが有効になる。

keycloak の起動

/opt/keycloak-6.0.1/bin/standalone.sh -Djboss.bind.address=0.0.0.0 -Djboss.http.port:8080 -Djboss.https.port=8523 -Djboss.bind.address.management=0.0.0.0 -Djboss.management.http.port=9000 -Djboss.management.https.port=9443

各引数の意味はこんな感じ。

  • -Djboss.bind.address=0.0.0.0: keycloak の listen アドレス。今回は Docker を使っているので、どこからでもアクセスできるように 0.0.0.0 を設定。
  • -Djboss.http.port=8080, -Djboss.https.port=8523: keycloak 接続ポート
  • -Djboss.bind.address.management=0.0.0.0: keycloak が動いている WildFly の管理用ページ(?) の listen アドレス。今回は Docker を使っているので、どこからでもアクセスできるように 0.0.0.0 を設定。
  • -Djboss.management.http.port=8080, -Djboss.management.http.port=9443: keycloak が動いている WildFly の管理用ポート

その他、ポート番号はオフセットで指定することもできる。こっちのほうが楽そう。

  • -Djboss.socket.binding.port-offset=10000

Realm とユーザーの追加

http://localhost:8080 に接続し、 Realm とユーザーを追加する。

Realm の追加

  1. 左上の Master のドロップダウンを選択
  2. Add realm ボタン押下
  3. realm の設定を入力
    1. Name: demo
    2. Enabled: ON
    3. Create 押下
    4. 左上のドロップダウンが Demo に変わっているのを確認

Realm に対するユーザーの追加

  1. 左のサイドメニューの Users を選択
  2. Add user ボタン押下
  3. ユーザー情報の追加
    1. Username: demo_user
    2. User Enabled: ON
    3. Save 押下
  4. Credentials タブを選択
  5. パスワード設定
    1. New Password, Password Confirmation を設定
    2. Reset Password 押下
    3. Change password 押下

アプリケーションの準備

アプリケーション用 WildFly のインストール

WildFly のダウンロードと展開

curl -L https://download.jboss.org/wildfly/17.0.1.Final/wildfly-17.0.1.Final.tar.gz -O
tar xf wildfly-17.0.1.Final.tar.gz

WildFly OpenID Connect adapter のダウンロード・展開

curl -L https://downloads.jboss.org/keycloak/6.0.1/adapters/keycloak-oidc/keycloak-wildfly-adapter-dist-6.0.1.tar.gz -O
tar xf keycloak-wildfly-adapter-dist-6.0.1.tar.gz -C wildfly-17.0.1.Final

WildFly OpenID Connect adapter のインストール

cd ./wildfly-17.0.1.Final/bin
./jboss-cli.sh --file=adapter-install-offline.cli

WildFly の実行

./standalone.sh -Djboss.bind.address=0.0.0.0 -Djboss.http.port=80 -Djboss.https.port=443 -Djboss.bind.address.management=0.0.0.0 -Djboss.management.http.port=9080 -Djboss.management.https.port=9523

keycloak を利用するアプリケーションの準備

keycloak を利用する側のアプリを準備。 keycloak の quickstarts のアプリを使う。

ソース取得

apt-get install -y git maven
git clone https://github.com/keycloak/keycloak-quickstarts

ビルド・デプロイ

cd keycloak-quickstarts/app-profile-jee-vanilla
mvn clean wildfly:deploy -Dwildfly.port=9080 -Dmaven.compiler.target=11 -Dmaven.compiler.source=11

demo_user がまだ許可されていないことを確認

http://localhost/vanilla にアクセス。

LOGIN ボタンを押すと、 BASIC 認証ダイアログが表示される。demo_user のユーザー名・パスワードでログインできないことを確認。

アプリケーションと demo Realm の紐づけ

アプリケーションと demo Realm を紐づけて、 demo Realm の情報でログインできるようにする。

keycloak 側の設定

  1. demo realm -> Clients を選択
  2. Create 押下
  3. クライアント情報入力
    1. Client ID: vanilla
    2. Client Protocol: openid-connect
    3. Root URL: http://localhost/vanilla
    4. Save 押下
  4. Installation タブ選択
    1. Format Option: Keycloak OIDC JBoss Subsystem XML

アプリケーションサーバー側の設定

/wildfly-17.0.1.Final/standalone/configuration/standalone.xml を編集する。

<subsystem xmlns="urn:jboss:domain:keycloak:1.1"/> を探して、以下のように修正する。

<subsystem xmlns="urn:jboss:domain:keycloak:1.1">
    <secure-deployment name="vanilla.war">
        <realm>demo</realm>
        <auth-server-url>http://localhost:8080/auth</auth-server-url>
        <public-client>true</public-client>
        <ssl-required>EXTERNAL</ssl-required>
        <resource>vanilla</resource>
    </secure-deployment>
</subsystem>

アプリケーションサーバーを再起動すると、この設定が有効になる。

demo_user でログインできることを確認

http://localhost/vanilla にアクセス。

LOGIN ボタンを押すと、 keycloak のログイン画面が表示される。

demo_user のユーザー名・パスワードでログインできることを確認。 初回ログインなのでパスワードの更新を求められる。

ログインが完了すると、次のような画面が表示される。

以上。

アプリケーションサーバー管理用ポートを開けて、サンプルアプリケーションのビルド・デプロイはホスト側でやるというのもありですね。

参考資料