Keycloak curl Authorization Code Flow with Proof Key for Code Exchange (PKCE) login. Usefull in scripts for obtaining an acess token from clients that do not have Direct Access Grants enabled.
#!/bin/bash # Keycloak Authorization Code Flow with Proof Key for Code Exchange (PKCE) # # Dependencies: # # 'brew install jq htmlq' # # https://github.com/jqlang/jq # https://github.com/mgdm/htmlq ### ---------------------------- usage() { printf 'Usage : %s -a %s -r %s -c %s -l %s -u %s\n' "${0##*/}" \ "<AUTHORITY>" "<REALM>" "<CLIENT_ID>" "<REDIRECT_URL>" "<USERNAME>" printf 'Example: %s -a "%s" -r "%s" -c "%s" -l "%s" -u "%s"\n' "${0##*/}" \ "https://keycloak.example.com/auth" \ "myrealm" \ "myclient" \ "https://myapp.example.com/" \ "myusername" printf '\nAccepts password from stdin, env AUTHORIZATION_CODE_LOGIN_PASSWORD, or prompt.\n' exit 2 } while getopts 'a:r:c:l:u:?h' c do case $c in a) authority=$OPTARG ;; r) realm=$OPTARG ;; c) clientId=$OPTARG ;; l) redirectUrl=$OPTARG ;; u) username=$OPTARG ;; h|?) usage ;; esac done [[ -z $authority || -z $realm || -z $clientId || -z $redirectUrl || -z $username ]] && usage password="$AUTHORIZATION_CODE_LOGIN_PASSWORD" [[ -z $password ]] && read -rp "password: " -s password ### ---------------------------- base64url() { tr -d '[:space:]' | tr -- '+/' '-_' | tr -d = ; } sha256sum() { printf "%s" "$1" | openssl dgst -binary -sha256 | openssl base64 -e | base64url ; } codeVerifier=$(openssl rand -base64 96 | base64url) cookieJar=$(mktemp "${TMPDIR:-/tmp}/cookie.jar.XXXX") trap 'rm "$cookieJar"' EXIT loginForm=$(curl -sSL --get --cookie "$cookieJar" --cookie-jar "$cookieJar" \ --data-urlencode "client_id=${clientId}" \ --data-urlencode "redirect_uri=$redirectUrl" \ --data-urlencode "scope=openid" \ --data-urlencode "response_type=code" \ --data-urlencode "code_challenge=$(sha256sum "$codeVerifier")" \ --data-urlencode "code_challenge_method=S256" \ "$authority/realms/$realm/protocol/openid-connect/auth" \ | htmlq -a action '#kc-form-login') loginForm=${loginForm//\&/\&} codeUrl=$(curl -sS --cookie "$cookieJar" --cookie-jar "$cookieJar" \ --data-urlencode "username=$username" \ --data-urlencode "password=$password" \ --write-out "%{redirect_url}" \ "$loginForm") code=${codeUrl##*code=} accessToken=$(curl -sS --cookie "$cookieJar" --cookie-jar "$cookieJar" \ --data-urlencode "client_id=$clientId" \ --data-urlencode "redirect_uri=$redirectUrl" \ --data-urlencode "code=$code" \ --data-urlencode "code_verifier=$codeVerifier" \ --data-urlencode "grant_type=authorization_code" \ "$authority/realms/$realm/protocol/openid-connect/token" \ | jq -r ".access_token") printf "%s" "$accessToken"
download:
authorization_code_login.sh