Keycloakユーザー管理

Azure上のUbuntuにKeycloakをインストールしてREST APIでユーザー管理をしてみます。

テスト環境は以下の通りです。

```
# uname -a
Linux ubuntu14 3.19.0-58-generic #64~14.04.1-Ubuntu SMP
Fri Mar 18 19:05:43 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

# java -version
java version "1.8.0_77"
Java(TM) SE Runtime Environment (build 1.8.0_77-b03)
Java HotSpot(TM) 64-Bit Server VM (build 25.77-b03, mixed mode)
```

まずはKeycloakをダウンロードして解凍します。

```
# wget https://downloads.jboss.org/keycloak/4.4.0.Final/keycloak-4.4.0.Final.tar.gz
# cd /opt
# tar zxvf /root/keycloak-4.4.0.Final.tar.gz
# mv keycloak-4.4.0.Final keycloak
```

つぎに管理ユーザー(root)を作成して起動します。-b 0.0.0.0とする事ですべてのIPアドレスからアクセスできるようになります。

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

Azureのファイアウォール設定を行うとブラウザでアクセスできますが、デフォルトではSSL化しないとログイン出来ないようです。

```
# ./bin/kcadm.sh config credentials --server http://l
ocalhost:8080/auth --realm master --user root
Logging into http://localhost:8080/auth as user root of realm master
Enter password: **********
# ./bin/kcadm.sh update realms/master -s sslRequired=NONE
```

REST APIのエンドポイントを確認します。

```
# curl http://ubuntu.japaneast.cloudapp.azure.com:8080/auth/realms/master/.well-known/openid-configuration
{"issuer":"http://ubuntu.japaneast.cloudapp.azure.com:8080/auth/realms/master",
"authorization_endpoint":"http://ubuntu.japaneast.cloudapp.azure.com:8080/auth/realms/master/protocol/openid-connect/auth",
"token_endpoint":"http://ubuntu.japaneast.cloudapp.azure.com:8080/auth/realms/master/protocol/openid-connect/token",
"token_introspection_endpoint":"http://ubuntu.japaneast.cloudapp.azure.com:8080/auth/realms/master/protocol/openid-connect/token/introspect",
"userinfo_endpoint":"http://ubuntu.japaneast.cloudapp.azure.com:8080/auth/realms/master/protocol/openid-connect/userinfo",
"end_session_endpoint":"http://ubuntu.japaneast.cloudapp.azure.com:8080/auth/realms/master/protocol/openid-connect/logout",
"jwks_uri":"http://ubuntu.japaneast.cloudapp.azure.com:8080/auth/realms/master/protocol/openid-connect/certs",
"check_session_iframe":"http://ubuntu.japaneast.cloudapp.azure.com:8080/auth/realms/master/protocol/openid-connect/login-status-iframe.html",
"grant_types_supported":["authorization_code","implicit","refresh_token","password",
"client_credentials"],"response_types_supported":["code","none","id_token","token","id_token token","code id_token","code token","code id_token token"],
"subject_types_supported":["public","pairwise"],
"id_token_signing_alg_values_supported":["RS256"],
"userinfo_signing_alg_values_supported":["RS256"],
"request_object_signing_alg_values_supported":["none","RS256"],
"response_modes_supported":["query","fragment","form_post"],
"registration_endpoint":"http://ubuntu.japaneast.cloudapp.azure.com:8080/auth/realms/master/clients-registrations/openid-connect",
"token_endpoint_auth_methods_supported":["private_key_jwt","client_secret_basic","client_secret_post",
"client_secret_jwt"],
"token_endpoint_auth_signing_alg_values_supported":["RS256"],
"claims_supported":["sub","iss","auth_time","name","given_name","family_name",
"preferred_username","email"],
"claim_types_supported":["normal"],
"claims_parameter_supported":false,"scopes_supported":["openid","address","email","offline_access","phone","profile"],
"request_parameter_supported":true,
"request_uri_parameter_supported":true,
"code_challenge_methods_supported":["plain","S256"],
"tls_client_certificate_bound_access_tokens":true}
```

管理ユーザーでaccess_tokenを取得します。

```
# curl -d "client_id=admin-cli" -d "username=root" \
-d "password=password" -d "grant_type=password" \
"http://ubuntu.japaneast.cloudapp.azure.com:8080/auth/realms/master/protocol/openid-connect/token"
{"access_token":"eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJtVlVOM
md4cDZpaW04VElPYWVqWnhLZElKUUpWTmMxYmxDeTRuejVsVTBvIn0.eyJqdGkiOiJjODhkMGY
0MC1mODBmLTQ5MjctYjU1ZS0zOTRiODQyM2ZmMjEiLCJleHAiOjE1MzY2NDgwMTgsIm5iZiI6M
CwiaWF0IjoxNTM2NjQ3OTU4LCJpc3MiOiJodHRwOi8vdWJ1bnR1MTQuamFwYW5lYXN0LmNsb3V
kYXBwLmF6dXJlLmNvbTo4MDgwL2F1dGgvcmVhbG1zL21hc3RlciIsImF1ZCI6ImFkbWluLWNsa
SIsInN1YiI6IjQyNzE5ZmJlLWRlMjktNGQ3Ni1iNTI1LWIzZmY1OGM5MmI0MSIsInR5cCI6IkJ
lYXJlciIsImF6cCI6ImFkbWluLWNsaSIsImF1dGhfdGltZSI6MCwic2Vzc2lvbl9zdGF0ZSI6I
jFkNTZiYjBhLTRkYjItNGQ2NS04NTNjLTZiM2JlM2RmZTFiNyIsImFjciI6IjEiLCJhbGxvd2V
kLW9yaWdpbnMiOltdLCJyZXNvdXJjZV9hY2Nlc3MiOnt9LCJzY29wZSI6ImVtYWlsIHByb2Zpb
GUiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsInByZWZlcnJlZF91c2VybmFtZSI6InJvb3QifQ.
e_Bqt8xAeUWgp_2lRy0fvqiwWi6zyE5wL23sylsF3q47mm4456g-xnWiL4BZRXNvtYDvhxaRHf
EPDQM-ps_EAOWIzaHJWP9dVtvps9WzGTJy-utPgZtR9e6TC_dPbBPgz12vO4TmyZZrK8cwJrdO
Hpm3j8t81TQp4DiJrw53DHtnGM5-uStLofPANGGhQIghzQ9OniEIM-asd6ot3VR-L7UV7YauNl
N-9lXTKoAt_IILR-KxpHspynrvWNTxvc0eGo89giuzJ8761M6zkQMrciQrfLFpeMRvyTkq2ii1
Nf6V1_U7kZ7XyGie_G_tv-SghxbFy7Y-vWyAeaRnlr57jg",
"expires_in":60,"refresh_expires_in":1800,"refresh_token":"eyJhbGciOiJSUzI
1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJtVlVOMmd4cDZpaW04VElPYWVqWnhLZElKUUpWT
mMxYmxDeTRuejVsVTBvIn0.eyJqdGkiOiIwNzYzNzU5Mi03ODk4LTQzZDctYWE5Yy1iOTY0NjA
1YzI5NzciLCJleHAiOjE1MzY2NDk3NTgsIm5iZiI6MCwiaWF0IjoxNTM2NjQ3OTU4LCJpc3MiO
iJodHRwOi8vdWJ1bnR1MTQuamFwYW5lYXN0LmNsb3VkYXBwLmF6dXJlLmNvbTo4MDgwL2F1dGg
vcmVhbG1zL21hc3RlciIsImF1ZCI6ImFkbWluLWNsaSIsInN1YiI6IjQyNzE5ZmJlLWRlMjktN
GQ3Ni1iNTI1LWIzZmY1OGM5MmI0MSIsInR5cCI6IlJlZnJlc2giLCJhenAiOiJhZG1pbi1jbGk
iLCJhdXRoX3RpbWUiOjAsInNlc3Npb25fc3RhdGUiOiIxZDU2YmIwYS00ZGIyLTRkNjUtODUzY
y02YjNiZTNkZmUxYjciLCJyZXNvdXJjZV9hY2Nlc3MiOnt9LCJzY29wZSI6ImVtYWlsIHByb2Z
pbGUifQ.HMzZETNPlMSiJWwe5oD3Q66NycQdpMaDootqDshMDQXzOCkht1ZnekDR6Umz4jUYZM
lW1MsUKtUpJ9TOlXabiONwZLgMvavdi9kuJrGB6sWh7CLdM1s4Roc8nBu0p_qY7WtRuCcph2hO
Pe-iKZ5xWvVAep4r-XJ1DPyAh1mUUf544o6dakROmCNNCwtWSLk7k5lo74iBVfcHiuVUnZZMIT
1pYpqy7z02B2wh5rcni75mqidIt6-16L7vYEiENZ2GeZtPS9lP2_vKptFLImvAaXOUqKooJTzl
D3iTyZp1mAJRpjNpgRHdXDObP2BdB58BD1Y6D8ZUkGRoiWyvkMJpjA",
"token_type":"bearer","not-before-policy":0,
"session_state":"1d56bb0a-4db2-4d65-853c-6b3be3dfe1b7",
"scope":"email profile"}
```

REST APIの使い方は以下にあります。
https://www.keycloak.org/docs-api/4.4/rest-api/index.html#_users_resource

REST APIでユーザー一覧を取得します。

```
# curl   -H "Authorization: bearer eyJ..." "http://ubuntu.japaneast.cloudapp.azure.com:8080/auth/admin/realms/master/users"
[{"id":"42719fbe-de29-4d76-b525-b3ff58c92b41","createdTimestamp":1536641131580,"username":"root","enabled"
:true,"totp":false,"emailVerified":false,"disableableCredentialTypes":["password"],"requiredActions":[],"notBefore":0,"access":{"manageGroupMembership":true,"view":true,"mapRoles":true,
"impersonate":true,"manage":true}}]
```

REST APIでユーザー追加。

```
# curl -H "Authorization: Bearer eyJ..."  -d '{"username" : "user01"}' "http://ubuntu.japaneast.cloudapp.azure.com:8080/auth/admin/realms/master/users"
```

REST APIでユーザー変更。

```
# curl -X put -H "Authorization: Bearer eyJ..."  -d '{"email" : "user01@test.local"}' "http://ubuntu.japaneast.cloudapp.azure.com:8080/auth/admin/realms/master/users/f536454d-7c96-443d-ad86-3bd654eadc4d"
```

REST APIでユーザー削除。

```
# curl -X delete -H "Authorization: Bearer eyJ..." "http://ubuntu.japaneast.cloudapp.azure.com:8080/auth/admin/realms/master/users/f536454d-7c96-443d-ad86-3bd654eadc4d"
```