Keycloakを使ってSAMLを理解する#1

Azure上のCentOSに、Keycloakとサンプルアプリを入れて、SAMLを使ったログインの動作検証を行ったメモです。

- **Keycloakを使ってSAMLを理解する#1**
    - ContOSのセットアップ
    - Keycloakのインストール
    - サンプルアプリのインストール
- [Keycloakを使ってSAMLを理解する#2](https://qiita.com/gebo/items/e1c2a26869510b236b9c)


#環境
- Azure
- CentOS Linux release 7.7.1908 (Core)
- OpenJDK 1.8.0
- Apache Maven 3.6.3
- Keycloak 8.0.1


#システム構成

![Untitled Diagram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252291/26767aa2-8603-b13f-78ff-f4b35a836918.png)


#1.CentOS
##CentOSのセットアップ
Azureに仮想マシンをデプロイします。

|項目|設定|
|:-:|:-:|
|仮想マシン名|CentOS7Keycloak|
|地域|東日本|
|イメージ|**CentOS-based 7.7**|
|サイズ|Standard B1s(1vcpu,1GiBのメモリ)|
|認証の種類|パスワード|
|ユーザー名|gebo|
|パスワード|xxxx|
|受信ポートを選択|SSH(22)|
|OSディスクの種類|Standard HDD|
|タイムゾーン|(UTC+09:00)大阪、札幌、東京|

**Keycloakが使うポート8080を開放します**
以下手順です。
[Azule]
→[仮想マシン]
→[CentOS7Keycloak]
→[受信ポートの規則を追加する]
→[受信セキュリティ規則の追加]
→**宛先ポート範囲=8080**
→追加

##接続確認
CentOSのデプロイが完了したらmac標準のターミナルアプリで接続確認しておきます。

```bash:ターミナル
$ssh gebo@x.x.x.x
[Password:xxxx
// これで接続できればOK
```

<img width="585" alt="suzuki_—_gebo_CentOS7Keycloak___—_ssh_gebo_52_185_169_82_—_80×24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252291/584fd852-8ec7-9829-d11b-8c083e4eb3ef.png">

##OpenJDKのインストール
CentOSに `OpenJDK 1.8.0` をインストールします。
この後、Mavenでビルドするのでdevelも入れます。

```bash:
// openJDKをインストール
$ sudo yum update -y
$ sudo yum install java-1.8.0-openjdk 
$ sudo yum install java-1.8.0-openjdk-devel

// 確認
$ java -version
openjdk version "1.8.0_232"
OpenJDK Runtime Environment (build 1.8.0_232-b09)
OpenJDK 64-Bit Server VM (build 25.232-b09, mixed mode)
$ javac -version
javac 1.8.0_232
```


#2.Keycloak

##2-1.Keycloakのインストール
CentOSにKeycloakをインストールします。
###ダウンロード
Keycloakはの8.0.1です。
以下サイトのStandalone server distributionをダウンロードして解凍します。
https://www.keycloak.org/downloads.html

```bash:
// ホームに戻ってから実行
$ cd
$ sudo wget https://downloads.jboss.org/keycloak/8.0.1/keycloak-8.0.1.zip
$ unzip keycloak-8.0.1.zip
```

###起動確認

```bash:
// memo:unzipしたkeycloak-8.0.1で実行
$ cd ~/keycloak-8.0.1
$ ./bin/standalone.sh -b 0.0.0.0
// なんだかんだあって
Keycloak 8.0.1 (WildFly Core 10.0.3.Fin$al) started
と出れば起動OK
```

<img width="585" alt="suzuki_—_gebo_CentOS7Keycloak___keycloak-8_0_1_—_ssh_gebo_52_185_169_82_—_80×24-2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252291/74db8634-9f32-279b-6ab9-68e21694b49e.png">

- memo:Keycloakを終了させるにはCtrl+C


ブラウザchromeから
`http:xxx.xxx.xx.xxx:8080/auth/`
に接続してWelcome画面が出てくればOK。
[You need ... admin user] と警告のようなものが表示されていますが、そこは次対応します。

<img width="825" alt="Welcome_to_Keycloak.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252291/bba9bcc8-7ba1-a5a0-4ab4-38b10b0ed9fe.png">

**これ以降はKeycloakが立ち上がっている状態で作業してください。**
サービスにしてしまってもいいかと思います。

##2-2.Keycloakの初期設定
- 管理者ユーザーの追加(admin/admin)
- HTTP接続許可設定

```bash:
// memo:unzipしたkeycloak-8.0.1で実行
$ cd ~/keycloak-8.0.1

// Keycloak の管理者ユーザーを作成
$ ./bin/add-user-keycloak.sh -r master -u admin -p admin

// 【重要】
// ここでKeycloakを再起動してください

// 管理者ID（ここではadmin）で認証情報を設定する
$ ./bin/kcadm.sh config credentials --server http://localhost:8080/auth --realm master --user admin
[Enter password:**** ←これはKeycloakの管理者パスワード(admin)

// SSL requiredを「NONE」に変更
$ ./bin/kcadm.sh update realms/master -s sslRequired=NONE
```

- Administration Consoleにログイン

ブラウザで
`http:xxx.xxx.xx.xxx:8080/auth/`
に接続して
Administration Console
Login
できればOK。

<img width="362" alt="Welcome_to_Keycloak-2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252291/7d25e9e3-8ddb-c2fa-8c49-d6ad0969529e.png">

<img width="286" alt="Log_in_to_Keycloak.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252291/ae9e89cc-2b0a-3b38-e992-2226b12679a3.png">

<img width="426" alt="Keycloak_Admin_Console.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252291/8c6d06be-451e-e107-0f36-2adbe80858e3.png">

##2-3.Keycloakへのロールとユーザー登録
これから使うサンプルアプリ用のデータを登録します。

###(1)Administration Consoleにログイン
adminでログインします。

###(2)ロールの登録

- デフォルトのMasterのレルム①が左メニュに表示されているかと思いますので、Rolesを選択②し、右側のビューから「Add Role」をクリック③します。

<img width="1013" alt="Keycloak_Admin_Console-6.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252291/1d071652-efca-18f7-02c1-81e77f844ef4.png">

- **user** Roleを作成します。

<img width="611" alt="Keycloak_Admin_Console-10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252291/e7dfca69-c7b1-0948-ee47-4597e0f30ba0.png">


###(3)ユーザー登録

- デフォルトのMasterのレルム①が左メニュに表示されているかと思いますので、Usersを選択②し、右側のビューから「View all users」をクリック③して登録済みユーザーが表示される④ことを確認します。
- 「Add user」をクリック⑤します。

<img width="880" alt="Keycloak_Admin_Console-3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252291/4123dfbf-e1b4-8101-eb32-746f61f8de24.png">

- Add user画面でユーザー情報を入力して「save」します。ここでは`test1`というユーザーを作成しました。

<img width="638" alt="Keycloak_Admin_Console-11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252291/18d510cd-1369-c0ef-a4af-917af1785a6a.png">


- 作成したユーザーの詳細画面に遷移するので、「Credential」からPasswordをセットします。

<img width="953" alt="Keycloak_Admin_Console-5.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252291/99b7fd87-2919-1dbc-64e5-add7e72c1e8b.png">

###(4)ユーザーとロールの紐づけ
ユーザー情報画面から「Role Mappings」を選択し、Available Rolesから今作成したユーザーを選択して「Add selected」します。
これでユーザーにロールが割り当てられます。

<img width="764" alt="Keycloak_Admin_Console-12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252291/fcbb0838-883e-aa6e-d5d4-b0abe6cb9f6e.png">

<img width="740" alt="Keycloak_Admin_Console-13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252291/7cdc8cd3-aacc-cca5-8ae2-64e6d7965a39.png">


#3.サンプルアプリ
Keycloak(Idp)とSAMLで接続するSP役のサンプルアプリをインストールします。
Keycloakのサイトに`quickstarts`というサンプル集がついているのですが、その中の**app-profile-saml**というものを使います。
Keycloakと同じ仮想マシン上にインストールします。

##Mavenのインストール
このサンプルアプリはビルドが必要なんで、CentOSにMavenをインストールします。

```bash:
// ホームディレクトリでやります
cd

// ダウンロード
$ curl -OL http://ftp.tsukuba.wide.ad.jp/software/apache/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz

// 展開
$ tar -xzvf apache-maven-3.6.3-bin.tar.gz

// optに移動
$ sudo mv apache-maven-3.6.3 /opt/

// 配置
$ cd /opt
$ sudo ln -s /opt/apache-maven-3.6.3 apache-maven

// apache-mavenというリンクができていればOK
$ ls -l
total 0
lrwxrwxrwx. 1 root root 23 Jan 13 03:08 apache-maven -> /opt/apache-maven-3.6.3
drwxrwxr-x. 6 gebo gebo 99 Jan 13 03:07 apache-maven-3.6.3
drwxr-xr-x. 2 root root  6 Oct 30  2018 rh
```

####mvnのパスを追加する

```bash:.bash_profileをviで開く
$ vi ~/.bash_profile
```

```config:.bash_profile
# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

# User specific environment and startup programs

# PATHに/opt/apache-maven/binを追加
PATH=$PATH:$HOME/.local/bin:$HOME/bin:/opt/apache-maven/bin

export PATH
```

```bash:変更した.bash_profileを反映する
$ source ~/.bash_profile
```

##クライアントアダプタのインストール
widlfly SAMLのクライアントアダプタをインストールします

```bash:
// ホームディレクトリでやります
cd

// ダウンロード
$ sudo wget https://downloads.jboss.org/keycloak/8.0.1/adapters/saml/keycloak-saml-wildfly-adapter-dist-8.0.1.zip

// ダウンロードしたzipをインストールする
$ cp keycloak-saml-wildfly-adapter-dist-8.0.1.zip ./keycloak-8.0.1
$ cd keycloak-8.0.1
$ unzip keycloak-saml-wildfly-adapter-dist-8.0.1.zip
$ ./bin/jboss-cli.sh -c --file=bin/adapter-elytron-install-saml.cli
// memo:{"outcome" => "failed"}の場合は失敗しているので、Keycloakを再起動してからやってみましょう
{"outcome" => "success"}
{
    "outcome" => "success",
    "response-headers" => {
        "operation-requires-reload" => true,
        "process-state" => "reload-required"
    }
}
{
    "outcome" => "success",
    "response-headers" => {"process-state" => "reload-required"}
}
{
    "outcome" => "success",
    "response-headers" => {"process-state" => "reload-required"}
}
{
    "outcome" => "success",
    "response-headers" => {"process-state" => "reload-required"}
}
{
    "outcome" => "success",
    "response-headers" => {"process-state" => "reload-required"}
}
{
    "outcome" => "success",
    "response-headers" => {"process-state" => "reload-required"}
}
{
    "outcome" => "success",
    "response-headers" => {"process-state" => "reload-required"}
}
{
    "outcome" => "success",
    "response-headers" => {"process-state" => "reload-required"}
}
```

##Quickstarts distributionのインストール

###app-profile-saml-jee-jspの設定
**README** [app-profile-saml-jee-jsp: HTML5 Profile Application with SAML](https://github.com/keycloak/keycloak-quickstarts/tree/latest/app-profile-saml-jee-jsp)の通りにやります。

- Open the Keycloak admin console
- レルムMasterのConfigureで`Client`を選択
- `Create`をクリック
- **Add Client**画面で以下設定:
    - Client ID: `app-profile-saml`
    - Client Protocol: `saml`
    - Save
- **App-profile-saml**画面で以下設定:
    - Valid Redirect URIs: `http://x.x.x.x:8080/app-profile-saml/*`
    - Base URL: `http://x.x.x.xxx:8080/app-profile-saml/`
    - Master SAML Processing URL: `http://x.x.x.x:8080/app-profile-saml/saml`
    - Force Name ID Format: `ON`
    - Save
- **Mappers**画面で以下設定:
    - `Add Buildtin`をクリック
    - X500 email,role list,X500 givenName,X500 surnameがリストに表示されるのですべてAddのチェックを付けて`Add selected`クリック
- **Installation**
    - Select `Keycloak SAML Adapter keycloak-saml.xml`
    - Click `Download`
    - Edit `keycloak-saml.xml` and replace `SPECIFY YOUR LOGOUT PAGE!` → `/index.jsp`
    - Move the file `keycloak-saml.xml` to the `config/` directory in the root of the quickstart 
- keycloak-saml.xmlをCentOSに転送する

```bash:macのコンソールアプリ
18:13:10 ~ $ scp -r /Users/suzuki/Downloads/keycloak-saml.xml gebo@x.x.x.x:/home/gebo/keycloak-quickstarts-latest/app-profile-saml-jee-jsp/config
```

###app-profile-saml-jee-jspのインストール
app-profile-saml-jee-jspはSAML接続のサンプルアプリです。
以下の手順でCentOSにデプロイします。

```bash:
// ホームディレクトリでやります
cd

// ダウンロード
sudo wget https://github.com/keycloak/keycloak-quickstarts/archive/latest.zip

// 解凍
unzip latest.zip

// アプリフォルダに移動
cd keycloak-quickstarts-latest
cd app-profile-saml-jee-jsp/

// デプロイ
mvn clean wildfly:deploy

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  59.403 s
[INFO] Finished at: 2020-01-13T09:37:49Z
[INFO] ------------------------------------------------------------------------
```

##サンプルを起動

- ブラウザから以下urlに接続すると、最初の画面が表示されるんで、LOGINをクリック

`http://x.x.x.x:8080/app-profile-saml`

<img width="582" alt="Keycloak_Example_App-2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252291/f92055d5-886e-9050-8b13-02bc48ccbd56.png">

- Keycloakのログイン画面が表示されるんで、さっき作成したユーザー(test1)でログインします。

<img width="633" alt="Log_in_to_Keycloak-3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252291/23b71039-36f6-61e5-1687-dd20f74dbfca.png">

- ログインしたユーザーの情報が表示されればOK。

何か設定がおかしいと、こういう画面にはならず、Forbiddenとかになったりします。

<img width="708" alt="Keycloak_SAML_Example_App.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252291/3cc3d181-27b3-2138-870b-481f98df43c0.png">

単にログインして、ユーザー情報を出しているだけですが、
- app-profile-saml=SP
- Keycloak=IdP
という関係でSAMLでやっています。
次回のSAMLの詳細を検証していきたいとおもいます。


#おつかれさまでした

SAMLというより、まずは、Keycloakのことが分かっていないと先に進めないところが大変...
次はどんな風にSAMLをやっているのか見ていきます。

- [Keycloakを使ってSAMLを理解する#2](https://qiita.com/gebo/items/e1c2a26869510b236b9c)