Skip to content

Instantly share code, notes, and snippets.

@leadelngalame1611
Last active November 21, 2022 07:26
Show Gist options
  • Save leadelngalame1611/8794efba238ecb822fb2793ca29b13d9 to your computer and use it in GitHub Desktop.
Save leadelngalame1611/8794efba238ecb822fb2793ca29b13d9 to your computer and use it in GitHub Desktop.
[Keycloak] script mapper
/**
* Available variables:
* user - the current user
* realm - the current realm
* token - the current token
* userSession - the current userSession
* keycloakSession - the current keycloakSession
*/
var ArrayList = Java.type('java.util.ArrayList');
var authorities = new ArrayList();
user.getGroups().forEach(function(group) {
var group_name = group.getName();
if(group_name === 'GO-Softcomweb-EC-Team-FT1-Member') {
authorities.add('ft1-read');
}
if(group_name === 'GO-Softcomweb-EC-Team-FT1-Keycloak-Admin-Checkout') {
authorities.add('ft1-write');
}
});
exports = authorities;
####################################################################
Keycloak OIDC Client
In client.json you can find an OIDC client that is importable into your Keycloak realm and contains the following additions:
maps ocn:department attribute so you can identify which department the user belongs to (e.g. MA-EC-XXX)
filters for relevant OCN groups by prefix (by default EC-Team-) to prevent header explosion which results in exceptions in many web servers for people who have a lot of group memberships
maps standard claims such as email, preferred_username
Importing the Client
Go to your Keycloak Realm -> Clients -> Create -> Import (select client.json) with openid-connect protocol.
You may need to adjust the redirect URLs as well as add some additional mappers if required.
Raw JS Mapper
If you just want to get the JS source code for the mapper that injects OCN group information:
/** * Available variables:
* user - the current user
* realm - the current realm
* token - the current token
* userSession - the current userSession
* keycloakSession - the current keycloakSession\n
*/
var ArrayList = Java.type('java.util.ArrayList');
var application_groups = new ArrayList();
user.getGroups().forEach(function(group) {
var group_name = group.getName();
if(group_name.startsWith('GO-Softcomweb-EC-Team-')) {
application_groups.add(group);
}
});
exports = application_groups;
################################ Example mapper2
/**
* Available variables:
* user - the current user
* realm - the current realm
* token - the current token
* userSession - the current userSession
* keycloakSession - the current keycloakSession
*/
var allowedOcnGroups = [ 'GO-Softcomweb-EC-Team-FT3-AUTH-ADMIN' ];
var ArrayList = Java.type('java.util.ArrayList');
var applicationGroups = new ArrayList();
user.getGroups().forEach(function(group) {
var group_name = group.getName();
if(allowedOcnGroups.indexOf(group_name) >= 0) {
applicationGroups.add(group_name);
}
});
exports = applicationGroups;
### End
Multivalued: ON
Token Claim Name: groups
Claim JSON Type: string
Add to ID token: ON
Add to access token: ON
add to userinfo: ON
## Set up a client for retrieving access token when using username and password
# Client ID: some Name
# Enable True
# Client Protocol: openid-connect
# Access Type: confidential
# Standard Flow Enabled: OFF
# Implicite Flow Enabled: OFF
# Direct Access Grants Enabled: ON
# Service Accounts Enabled: OFF
# Authorization Enabled: OFF
## Set up client for retrieving access token when using client id and secret
# Client ID: some Name
# Enable True
# Client Protocol: openid-connect
# Access Type: confidential
# Standard Flow Enabled: OFF
# Implicite Flow Enabled: OFF
# Direct Access Grants Enabled: ON
# Service Accounts Enabled: ON
# Authorization Enabled: ON
## Set up client for retrieving token for a public web service
# Client ID: some Name
# Enable True
# Client Protocol: openid-connect
# Access Type: public
# Standard Flow Enabled: ON
# Implicite Flow Enabled: ON
# Direct Access Grants Enabled: ON
# Service Accounts Enabled: OFF
# Authorization Enabled: OFF
# Valid Redirect URLs: specify the valid url for your service
response=$(curl -s -XPOST localhost:8080/auth/realms/si/protocol/openid-connect/token --header 'content-type: application/x-www-form-urlencoded' --data grant_type=password --data client_id=api-client --data client_secret=0312b15d-e601-4800-a9a2-5a977d8a8100 --data username=leadel --data password=sG1ljpSR3D5EnIvCg0kYXJmEwZajLsXQNpP63Jdp)
access_token=$(echo $response | jq '.access_token' -r)
Now you can make calls with the access token provides it has enough permissions to access the specific resource you want to retrieve
curl -xPOST http://localhost:8080/auth/admin/realms/si/users \
--header 'authorization: Bearer <access_token>' \
--header 'content-type: application/json' \
--data '{
"username": "leacoco",
"enabled": true,
"email": "leacoco@localhost.com"
}'
curl -XPOST http://localhost:8080/auth/admin/realms/si/users --header "authorization: Bearer $access_token" --header 'content-type: application/json' --data '{
"username": "leacoco",
"enabled": true,
"email": "leacoco@localhost.com"
}'
##################### Or use the following script ###########################
## Note that the below will retrieve a token from admin cli client in the master realm using the admin username and password
#!/usr/bin/env bash
set -eo pipefail
KC_USERNAME="admin"
KC_PASSWORD="changeit"
KC_REALM="master"
KC_HOST="http://localhost:8080"
OIDC_ACCESS_TOKEN=$(curl --request POST \
--url $KC_HOST/auth/realms/$KC_REALM/protocol/openid-connect/token \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data grant_type=password \
--data client_id=admin-cli \
--data username=$KC_USERNAME \
--data password=$KC_PASSWORD | jq -r '.access_token')
curl --request POST \
--url $KC_HOST/auth/admin/realms/$KC_REALM/users \
--header "Authorization: Bearer $OIDC_ACCESS_TOKEN" \
--header 'Content-Type: application/json' \
--data '{
"username": "api_test_1",
"enabled": true,
"email": "test@example.com"
}'
######################## Using the functions in ~/.bash_alias file ###############################################
function get_access_token {
if [[ $1 == "-h" ]]; then
echo "Run the command as follows"
echo "get_access_token <Keycloak server url> <realm_name>"
return
fi
HOST=$1
REALM_NAME=$2
CLIENT_ID="admin-cli"
TOKEN_URL="${HOST}/auth/realms/${REALM_NAME}/protocol/openid-connect/token"
if [ -f "${HOME}/.ocn" ]; then
USERNAME=$(cat $HOME/.ocn | cut -d: -f1)
PASSWORD=$(cat $HOME/.ocn | cut -d: -f2)
else
read -p 'USERNAME: ' USERNAME
read -s -p 'PASSWORD: ' PASSWORD
echo
fi
CURL_OPTS="--data-urlencode username=$USERNAME --data-urlencode password=$PASSWORD"
ACCESS_TOKEN=$(curl --header 'Content-Type: application/x-www-form-urlencoded' \
--data "client_id=${CLIENT_ID}" \
--data grant_type=password \
${CURL_OPTS} \
${TOKEN_URL} 2> /dev/null \
| jq -r .access_token)
echo ${ACCESS_TOKEN}
}
## Source the file
>> source ~/.bash_alias
## Get Access token for a REALM:
>> TOKEN=$(get-access-token live si-account-management) ##first variable Environment, second variable realm name
#################################Token Decoder ###############################################
function decode_base64() {
local len=$((${#1} % 4))
local result="$1"
if [[ $len -eq 2 ]]; then
result="${result}=="
elif [[ $len -eq 3 ]]; then
result="${result}="
fi
echo "$result" | base64 --decode
}
function decode_jwt(){
decode_base64 $(echo -n $2 | cut -d "." -f $1) | jq .
}
# Decode JWT header
function jwth() {
decode_jwt 1 $@
}
function jwtp() {
decode_jwt 2 $@
}
function decode_access_token {
if [[ $1 == "-h" ]]; then
echo "Run the command as follows"
echo "decode_access_token <token>"
return
else
ACCESS_TOKEN=$1
fi
jwtp ${ACCESS_TOKEN}
}
## Source the file
>> source ~/.bash_alias
## Decode Access token:
>> decode_access_token $TOKEN
>> decode_access_toke $(get-access-token live si-account-management)
##################################################################################################################
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment