2022-10-12 14:22:22 +00:00
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
2022-10-24 21:53:02 +00:00
|
|
|
function setup_traps() {
|
|
|
|
trap 'error_handler ${LINENO} $?' ERR
|
|
|
|
}
|
|
|
|
function remove_traps() {
|
|
|
|
trap - ERR
|
|
|
|
}
|
|
|
|
|
2022-10-12 14:22:22 +00:00
|
|
|
function error_handler() {
|
|
|
|
>&2 echo "Exited with BAD EXIT CODE '${2}' in ${0} script at line: ${1}."
|
|
|
|
exit "$2"
|
|
|
|
}
|
2022-10-24 21:53:02 +00:00
|
|
|
setup_traps
|
|
|
|
|
2022-10-12 14:22:22 +00:00
|
|
|
set -o errtrace -o errexit -o nounset -o pipefail
|
|
|
|
|
2023-01-20 18:21:52 +00:00
|
|
|
realm_name="${1:-}"
|
|
|
|
if [[ -z "$realm_name" ]]; then
|
|
|
|
realm_name="spiffworkflow"
|
|
|
|
fi
|
|
|
|
|
2022-10-12 14:22:22 +00:00
|
|
|
if ! docker network inspect spiffworkflow > /dev/null 2>&1; then
|
|
|
|
docker network create spiffworkflow
|
|
|
|
fi
|
2022-12-15 02:29:46 +00:00
|
|
|
|
|
|
|
# https://stackoverflow.com/a/60579344/6090676
|
|
|
|
container_name="keycloak"
|
2023-03-29 17:47:03 +00:00
|
|
|
container_regex="^keycloak$"
|
|
|
|
if [[ -n "$(docker ps -qa -f name=$container_regex)" ]]; then
|
2022-12-15 02:29:46 +00:00
|
|
|
echo ":: Found container - $container_name"
|
2023-03-29 17:47:03 +00:00
|
|
|
if [[ -n "$(docker ps -q -f name=$container_regex)" ]]; then
|
2022-12-15 02:29:46 +00:00
|
|
|
echo ":: Stopping running container - $container_name"
|
|
|
|
docker stop $container_name
|
|
|
|
fi
|
|
|
|
echo ":: Removing stopped container - $container_name"
|
|
|
|
docker rm $container_name
|
|
|
|
fi
|
|
|
|
|
2022-10-12 14:22:22 +00:00
|
|
|
docker run \
|
|
|
|
-p 7002:8080 \
|
|
|
|
-d \
|
|
|
|
--network=spiffworkflow \
|
|
|
|
--name keycloak \
|
|
|
|
-e KEYCLOAK_LOGLEVEL=ALL \
|
|
|
|
-e ROOT_LOGLEVEL=ALL \
|
|
|
|
-e KEYCLOAK_ADMIN=admin \
|
2023-01-11 19:52:12 +00:00
|
|
|
-e KEYCLOAK_ADMIN_PASSWORD=admin \
|
|
|
|
quay.io/keycloak/keycloak:20.0.1 start-dev \
|
2022-10-12 14:22:22 +00:00
|
|
|
-Dkeycloak.profile.feature.token_exchange=enabled \
|
|
|
|
-Dkeycloak.profile.feature.admin_fine_grained_authz=enabled
|
|
|
|
|
2022-10-28 17:42:21 +00:00
|
|
|
script_dir="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"
|
2023-01-20 18:21:52 +00:00
|
|
|
cp "${script_dir}/../realm_exports/${realm_name}-realm.json" /tmp/${realm_name}-realm.json
|
2023-05-26 15:10:57 +00:00
|
|
|
spiff_subdomain="for-local-dev.spiffworkflow.org"
|
2023-05-26 16:03:04 +00:00
|
|
|
perl -pi -e "s/replace-me-with-spiff-backend-host-and-path/${spiff_subdomain}/g" /tmp/${realm_name}-realm.json
|
2023-01-20 18:21:52 +00:00
|
|
|
docker cp /tmp/${realm_name}-realm.json keycloak:/tmp
|
2022-10-12 14:22:22 +00:00
|
|
|
|
2022-10-24 21:53:02 +00:00
|
|
|
sleep 20
|
|
|
|
remove_traps
|
|
|
|
set +e
|
2023-01-20 18:21:52 +00:00
|
|
|
import_output=$(docker exec keycloak /opt/keycloak/bin/kc.sh import --file /tmp/${realm_name}-realm.json 2>&1)
|
2022-10-24 21:53:02 +00:00
|
|
|
setup_traps
|
|
|
|
set -e
|
|
|
|
if ! grep -qE "Import finished successfully" <<<"$import_output"; then
|
|
|
|
echo -e "FAILED: $import_output"
|
|
|
|
exit 1
|
|
|
|
fi
|
2022-10-12 14:22:22 +00:00
|
|
|
|
|
|
|
echo 'imported realms'
|
|
|
|
|
|
|
|
if [ "${TURN_OFF_SSL:-}" == "true" ]; then
|
2022-10-17 14:20:35 +00:00
|
|
|
docker exec -it keycloak /opt/keycloak/bin/kcadm.sh config credentials --server http://localhost:8080 --realm master --user admin --password admin
|
2022-10-12 14:22:22 +00:00
|
|
|
docker exec -it keycloak /opt/keycloak/bin/kcadm.sh update realms/master -s sslRequired=NONE
|
2023-01-20 18:21:52 +00:00
|
|
|
docker exec -it keycloak /opt/keycloak/bin/kcadm.sh update realms/${realm_name} -s sslRequired=NONE
|
2022-10-12 14:22:22 +00:00
|
|
|
echo 'turned off SSL requirement'
|
|
|
|
fi
|
|
|
|
|
|
|
|
docker stop keycloak
|
|
|
|
docker start keycloak
|
|
|
|
|
|
|
|
|
|
|
|
# to export:
|
|
|
|
# /opt/keycloak/bin/kc.sh export --dir /tmp/hey --users realm_file
|
|
|
|
# change any js policies to role policies - just copy the config of one and change the type to role
|
|
|
|
# https://github.com/keycloak/keycloak/issues/11664#issuecomment-1111062102
|
|
|
|
#
|
|
|
|
# if docker exec commands fail below then attempt to import by adding a new realm in the webui
|
|
|
|
|
|
|
|
# NOTE: creds - user1 / password
|
|
|
|
|
|
|
|
#### Example resource_set call
|
|
|
|
# GET /realms/quarkus/authz/protection/resource_set?matchingUri=true&deep=true&max=-1&exactName=false&uri=%2Fapi%2Fusers%2Fme HTTP/1.1..Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJjZklBRE5feHhDSm1Wa1d5Ti1QTlhFRXZNVVdzMnI2OEN4dG1oRUROelhVIn0.eyJleHAiOjE2NTcxMzgzNzAsImlhdCI6MTY1NzEzODA3MCwianRpIjoiY2I1OTc0OTAtYzJjMi00YTFkLThkNmQtMzBkOGU5YzE1YTNlIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo0MzI3OS9yZWFsbXMvcXVhcmt1cyIsImF1ZCI6ImFjY291bnQiLCJzdWIiOiI5NDhjNTllYy00NmVkLTRkOTktYWE0My0wMjkwMDAyOWI5MzAiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJiYWNrZW5kLXNlcnZpY2UiLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsib2ZmbGluZV9hY2Nlc3MiXX0sInJlc291cmNlX2FjY2VzcyI6eyJiYWNrZW5kLXNlcnZpY2UiOnsicm9sZXMiOlsidW1hX3Byb3RlY3Rpb24iXX0sImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJtYW5hZ2UtYWNjb3VudC1saW5rcyIsInZpZXctcHJvZmlsZSJdfX0sInNjb3BlIjoiZW1haWwgcHJvZmlsZSIsImNsaWVudEhvc3QiOiIxNzIuMTcuMC4xIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJjbGllbnRJZCI6ImJhY2tlbmQtc2VydmljZSIsInByZWZlcnJlZF91c2VybmFtZSI6InNlcnZpY2UtYWNjb3VudC1iYWNrZW5kLXNlcnZpY2UiLCJjbGllbnRBZGRyZXNzIjoiMTcyLjE3LjAuMSIsImVtYWlsIjoic2VydmljZS1hY2NvdW50LWJhY2tlbmQtc2VydmljZUBwbGFjZWhvbGRlci5vcmcifQ.VRcdoJQO5KWeDFprl6g21Gp9lAqLH1GUAegZPslI9lcL7wdEDLauleTs7cr9ODvXpBbbWVZirP445H3bIfEpyZ2UiKeoEYB6WvR2r_hIHCbNGrV9klkCVjQSuCtdB-Zf3OWHXctz_warlNXF4i4VLtkettlxeGRTVpqT-_lO-y2PhHVNe7imEcnceoKWZQe-Z0JBAJ1Gs2_mj_vgL8V2ZKAd7x0uuAcNyqo4Kmvqh75vkhIuGYAbWfY--wdv8cuphNpbKCGoz27n-D_Im8tW00B1_twctwXo8yfZHp46o1yERbTCS1Xu_eBFufKB21au6omxneyKSD47AfHLR_ymvg..Host: localhost:43279..Connection: Keep-Alive....
|
|
|
|
# #
|
|
|
|
# T 127.0.0.1:43279 -> 127.0.0.1:39282 [AP] #127
|
|
|
|
# HTTP/1.1 200 OK..Referrer-Policy: no-referrer..X-Frame-Options: SAMEORIGIN..Strict-Transport-Security: max-age=31536000; includeSubDomains..Cache-Control: no-cache..X-Content-Type-Options: nosniff..X-XSS-Protection: 1; mode=block..Content-Type: application/json..content-length: 236....[{"name":"usersme","owner":{"id":"0ac5df91-e044-4051-bd03-106a3a5fb9cc","name":"backend-service"},"ownerManagedAccess":false,"displayName":"usersme","attributes":{},"_id":"179611c3-be58-4ba2-95b2-4aacda3cc0f1","uris":["/api/users/me"]}]
|
|
|
|
# #
|
|
|
|
# T 127.0.0.1:39282 -> 127.0.0.1:43279 [AP] #128
|
|
|
|
# POST /realms/quarkus/protocol/openid-connect/token HTTP/1.1..Authorization: Basic YmFja2VuZC1zZXJ2aWNlOnNlY3JldA==..Content-Length: 1231..Content-Type: application/x-www-form-urlencoded; charset=UTF-8..Host: localhost:43279..Connection: Keep-Alive....
|
|
|
|
# #
|
|
|
|
# T 127.0.0.1:39282 -> 127.0.0.1:43279 [AP] #129
|
|
|
|
# audience=backend-service&grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Auma-ticket&permission=179611c3-be58-4ba2-95b2-4aacda3cc0f1&subject_token=eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJjZklBRE5feHhDSm1Wa1d5Ti1QTlhFRXZNVVdzMnI2OEN4dG1oRUROelhVIn0.eyJleHAiOjE2NTcxMzgzNzYsImlhdCI6MTY1NzEzODA3NiwiYXV0aF90aW1lIjoxNjU3MTM4MDc2LCJqdGkiOiI0ZjMyYzljNS05NzY3LTQ0YzAtOTBlNi1kZmJhNjFmMmJmNDgiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjQzMjc5L3JlYWxtcy9xdWFya3VzIiwic3ViIjoiZWI0MTIzYTMtYjcyMi00Nzk4LTlhZjUtODk1N2Y4MjM2NTdhIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoiYmFja2VuZC1zZXJ2aWNlIiwibm9uY2UiOiI5SklBc2RhIiwic2Vzc2lvbl9zdGF0ZSI6IjBlZTVkNjRmLWYxM2EtNDg1Yy1hNzBhLTJmMDA0YjQ3MWIwNyIsInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJ1c2VyIl19LCJzY29wZSI6Im9wZW5pZCBlbWFpbCBwcm9maWxlIiwic2lkIjoiMGVlNWQ2NGYtZjEzYS00ODVjLWE3MGEtMmYwMDRiNDcxYjA3IiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhbGljZSJ9.Jjz0GYaApd_b05YOSe_Eq0tsFQk7qd-vGgIyjdeeEJAAA5xhS2f_DMpwiBLAPibk-gFnGf5CuLynA0z5bxE5vlbQHX9-aKxH8AEixDFkUsnfn7PN1NQtiG-Jj5cfuLxOShy2X2EOScZVTdRc9PgO_Xsb7ltDrtwtQ6eKOYVt-mqd7PR3cWJHjTldh4tiibjrKPccyZNBNC3W03pno3WLRVaG09Kotcsj1e5oS0safAcxACa3CSfchnY88E7Qwi1mva2F4X-gUar5-Zn2yT2iu8vqH3BCHzz8frAsYv1dOougRBaMfayLiFgKo7ZjsOI8OfPDSm7PEOMFEgHEHIloiw
|
|
|
|
# ##
|
|
|
|
# T 127.0.0.1:43279 -> 127.0.0.1:39282 [AP] #131
|
|
|
|
# HTTP/1.1 403 Forbidden..Referrer-Policy: no-referrer..X-Frame-Options: SAMEORIGIN..Strict-Transport-Security: max-age=31536000; includeSubDomains..Cache-Control: no-store..X-Content-Type-Options: nosniff..Pragma: no-cache..X-XSS-Protection: 1; mode=block..Content-Type: application/json..content-length: 62....{"error":"access_denied","error_description":"not_authorized"}
|
|
|
|
########
|
|
|
|
|
|
|
|
#### quarkus for example
|
|
|
|
# https://quarkus.io/guides/security-keycloak-authorization
|
|
|
|
# from that guide, we ultimately found that we hit GET /resource_set described at:
|
|
|
|
# https://github.com/keycloak/keycloak-documentation/blob/main/authorization_services/topics/service-protection-resources-api-papi.adoc
|
|
|
|
# when we get the resource, we just hit the token endpoint and provide the resource and scope, and token will say pass or fail.
|
|
|
|
# More info:
|
|
|
|
# * https://stackoverflow.com/a/58861610/6090676
|
|
|
|
# * https://github.com/keycloak/keycloak/discussions/10044
|