Docker, Keycloakを利用しアクセストークンを指定してAPI実行する

## 目次
- DockerからKeycloak起動
- ポート変更方法
- Keycloakのクライアントアプリとユーザーアカウントの登録
- Spring BootのREST APIの作成
- リソースサーバー設定：認可サーバーの設定
- 認証アクセス設定
- アクセストークンを指定してAPI実行
- スコープによるアクセストークン発行
- ユーザーによるアクセストークン発行
- アクセストークンの内容確認
- ユーザー情報確認

## 参考サイト
- [KeycloakとSpringBoot/SecurityでOpenID Connect(リソースサーバー編)](https://qiita.com/kasa_le/items/259792d3ae4df7f1d2b2)

## DockerからKeycloak起動
DockerとKeycloakで世界最速OpenID Connectの為、DockerからKeycloakを実行する事にする。
参考サイト：https://www.keycloak.org/getting-started/getting-started-docker

```
docker run -p 8080:8080 -e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=admin quay.io/keycloak/keycloak:12.0.1
```

- ポート変更後は以下になる。

```
docker run -p 8088:8088 -e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=admin quay.io/keycloak/keycloak:12.0.1
```

## ポート変更方法
他のアプリとポート番号被ると困るので、ポート番号を8088に変更する。

```
docker run -p 8088:8088 -e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=admin quay.io/keycloak/keycloak:12.0.1 -Djboss.http.port=8088
```

## Keycloakのクライアントアプリとユーザーアカウントの登録
- この [Link](https://qiita.com/nayylin/items/e9dd41d0cdf923c6d0c9) にて、Keycloakの操作を確認し、クライアントアプリとユーザーアカウントの登録を行う。
※上記でポート番号変更している為、Keycloakのリンクのポート番号も上記通り[8088]になります。
ログインユーザーは[admin/admin]になる。
- Keycloakのサンプルクライアントアプリ登録する時にも、変更後ポート番号で登録すること。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602725/eccad359-ae76-d15e-1b60-100f688c54d6.png)


## Spring BootプロジェクトにSpring Securityを導入したREST APIの作成
この [Link](https://qiita.com/nayylin/items/939b8376e7ef50d9f7e3) の通り、REST APIを作成する。

ここまでで、API実行するとログインが必要になる。その為以降の手順として、ログインしないでアクセストークンを利用してAPI実行出来るようにする。

## リソースサーバー設定：認可サーバーの設定
- 上記で作成したプロジェクトのapplication.propertiesに認可サーバー情報を設定する。

```
application.properties

# 認可サーバーのIssuer Identifier
spring.security.oauth2.resourceserver.jwt.issuer-uri= http://localhost:8088/auth/realms/realm1
```

- API実行すると[401=Unauthorized]になる。この状態は正常な動作である。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602725/9ab4f67d-93f1-bf1d-d208-7fcd1e4e2285.png)

## 認証アクセス設定
Keycloakにアプリを登録しアクセストークンを取得し、それを使って認証アクセスを試す。

## ①Keycloakにてクライアントアプリを追加する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602725/e9ad597b-8c1e-7fe4-af9b-a09aedafbc29.png)

- 以下を設定し保存する。<br/>
Access Type=Confidential<br/>
Authorization Enabled=ON<br/>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602725/d0c58d08-4d5b-2acf-8b49-c20e0591fa15.png)


## ②アクセストークンを指定してAPI実行
② -１）Client Secretsの取得
Keycloakのクライアントアプリの[Credentials]の[Secret]をコピーする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602725/5ba3eb20-19b9-12bc-d6f2-5af75aac8f1e.png)

② -２）【Postmanで実行する場合】アクセストークンを指定してAPI実行
② -２）i）アクセストークンの取得
POSTと「http://localhost:8088/auth/realms/realm1/protocol/openid-connect/token 」と３つのパラメータを設定して実行するとアクセストークンが取得出来る。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602725/354cd8c6-a688-9635-562e-11d7ed92a7b3.png)

```
Response: 
{
    "access_token": "xxxxxxxxxxxxx",
    "expires_in": 300,
    "refresh_expires_in": 0,
    "token_type": "Bearer",
    "not-before-policy": 0,
    "scope": "profile email"
}
```
※アクセストークン内容確認はこの [Link](https://jwt.io/) にて確認出来る。の中身を見る

② -２）ii）アクセストークンを指定してAPI実行すると、実装内容が確認出来るようになる。
※アクセストークンが期限切れた場合は、[401=Unauthorized]になる事もある。この場合は再度アクセストークンを取得し、API実行する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602725/ad0a5a90-e7e3-f0fe-75f6-a0a13b59ae73.png)

または
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602725/e1378646-b439-2011-99d4-ef5dc292f3c4.png)



② -３）【エンドポイントで実行する場合】アクセストークンを指定してAPI実行
② -３）i）アクセストークンの取得

```
curl -X POST "http://localhost:8088/auth/realms/[作成したrealm名]/protocol/openid-connect/token" --data "grant_type=client_credentials&client_secret={コピーしたClient Secrets}&client_id=[作成したclient名]"

```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602725/8f5f7abf-4761-c8d4-0e3a-5d9a36769670.png)

② -３）ii）アクセストークンを指定してAPI実行すると、実装内容が確認出来るようになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602725/01789fc4-4760-ff5d-5e88-e7e0b152bd2b.png)

## スコープによるアクセストークン発行
こちらは、スコープによりアクセストークンを発行しAPIを実行する事になる。
[スコープのトークンによるAPI実行](https://qiita.com/nayylin/items/3be85a6b7daf8a577f55)を参照してください。

## ユーザーによるアクセストークン発行
こちらは、ユーザーによりアクセストークンを発行しAPIを実行する事になる。
[ユーザーのトークンによるAPI実行](https://qiita.com/nayylin/items/57b3f6661a564b64092e)を参照してください。

## アクセストークンの内容確認


## ユーザー情報確認