Open firewall ports:
Tip
|
It is not mandatory to perform this step unless you have compatibility issues with yor firewall. |
firewall-cmd --add-port 8090/tcp --permanent
firewall-cmd --add-port 8043/tcp --permanent
Important
|
It is necessary to map two ports since one is needed for the keycloak console. In this case, you need to map the 8090 with the 8080 because Quarkus is currently using the 8080. |
podman pod create -p 8090:8080 -p 8543:8443 --name trikora_keycloak_quarkus_client_pod
Firstly it is necessary to copy the realm.json in the tmp/keycloak_tmp/ (local) directory. As this directory is volatile, you have to do this operation each time you restart your PC.
You need to be located in your project root directory in order to perform the following commands.
mkdir /tmp/keycloak_tmp/
cp src/test/resources/trikora-realm.json /tmp/keycloak_tmp/
Then you can execute:
Note
|
In the current version of keycloak, it is not possible to run keycloak with an initial database, so you have to run the pod with an empty keycloak and then import the realm.json with the command line (see below). For that reason the flag -e KEYCLOAK_IMPORT=/tmp/trikora-realm.json has been removed from the run command.
|
podman run --name trikora_keycloak_quarkus_client --security-opt label=disable \
-d --pod trikora_keycloak_quarkus_client_pod \
-e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=admin \
-v /tmp/keycloak_tmp/:/tmp/ \
quay.io/keycloak/keycloak:15.0.2
Note
|
the --rm flag is set for deleting the pod after the execution. You can kill the process with ^C . Another option would be to launch the command with the -dflag instead of the --rm one. The -d option will launch the pod as a daemon. |
-
Link to keycloak console: https://localhost:8543/auth/admin/master/console/#/realms/trikorasolutions
-
You can access the roles section by the left navigator in the main page or clicking here:
https://localhost:8543/auth/admin/master/console/#/realms/trikorasolutions/roles -
In this section you can add roles to our application that will be saved in the realms.json that you have located in the tmp directory.
-
In the user section, you can edit all the information regarding the user such as the email, password …
but indeed you have the possibility of assigning new roles to the user as well as enroll them to different groups.
-
In this section we will describe how keycloak filter the URLs with the proper permissions.
-
Firstly, you have to locate in Clients → backend-service → Authorization → Settings → Resources.
Link: https://localhost:8543/auth/admin/master/console/#/realms/trikorasolutions/clients/0ac5df91-e044-4051-bd03-106a3a5fb9cc/authz/resource-server/resource -
Then, you have to create a new resource where you will establish the URLs that are going to be restricted. For doing so, there is a button
Create
in the upper-right side of the main layout. -
After that, it is necessary to add an Associated Permission to the Resource, now you have to decide who is going to have access to the service by creating a new policy. A policy, may be a Role, Group, Client scope or even a single user.
Once you have linked the policy to the resource, just the desired users could access to the services. -
If a user without the proper permissions tries to access the service, keycloak will return a http response with status 403 (FORBIDDEN).
It is important to have at least one user with enough privileges to communicate with keycloak through the REST endpoints, in order to develop such a thing you
can create a new group and then in the "role-mappings" section of the desired group, then click on "client-roles" after that select the "realm-management" client.
At this point, you should see the roles in the "Available Roles" window. Select the roles you want give to the group and click on "Add selected".
Lastly, do not forget to add the admin user to the group in the Users section of the keycloak console.
-
In this section we will describe how to export a realm.json in a single file from a running container using podman.
[podman | docker] exec -it <pod_name> opt/jboss/keycloak/bin/standalone.sh
-Djboss.socket.binding.port-offset=<interger_value> Docker recommend an offset of 100 at least
-Dkeycloak.migration.action=[export | import]
-Dkeycloak.migration.provider=[singleFile | dir]
-Dkeycloak.migration.dir=<DIR TO EXPORT TO> Use only iff .migration.provider=dir
-Dkeycloak.migration.realmName=<REALM_NAME_TO_EXPORT>
-Dkeycloak.migration.usersExportStrategy=[DIFFERENT_FILES | SKIP | REALM_FILE | SAME_FILE]
-Dkeycloak.migration.usersPerFile=<integer_value> Use only iff .usersExportStrategy=DIFFERENT_FILES
-Dkeycloak.migration.file=<FILE TO EXPORT TO>
podman exec -it trikora_keycloak_quarkus_client /opt/jboss/keycloak/bin/standalone.sh \
-Djboss.socket.binding.port-offset=100 \
-Dkeycloak.migration.action=export \
-Dkeycloak.migration.provider=singleFile \
-Dkeycloak.migration.realmName=trikorasolutions \
-Dkeycloak.migration.usersExportStrategy=REALM_FILE \
-Dkeycloak.migration.file=/tmp/trikora-realm.json
[podman | docker] exec -it <container_name> <PATH_TO_KEYCLOAK_IN_THE_POD>/bin/standalone.sh
-Djboss.socket.binding.port-offset=100
-Dkeycloak.migration.action=import
-Dkeycloak.migration.provider=singleFile
-Dkeycloak.migration.realmName=quarkus
-Dkeycloak.migration.usersExportStrategy=REALM_FILE
-Dkeycloak.migration.file=<FILE_TO_IMPORT>
-Dkeycloak.profile.feature.upload_scripts=enabled
-Dkeycloak.profile.feature.scripts=enabled
-Dkeycloak.migration.strategy=[OVERWRITE_EXISTING | IGNORE_EXISTING]
Important
|
When a realm is imported from the command line, the keycloak console is not updated due to a version bug. In order to see the imported realm, it is necessary to create another realm (empty, only need to enter the realm name). This action will force the console table to be updated, this is a keycloak bug, so we hope that it could be fixed in futures releases. |
podman exec -it trikora_keycloak_quarkus_client /opt/jboss/keycloak/bin/standalone.sh \
-Djboss.socket.binding.port-offset=100 \
-Dkeycloak.migration.action=import \
-Dkeycloak.migration.provider=singleFile \
-Dkeycloak.migration.realmName=trikorasolutions \
-Dkeycloak.migration.usersExportStrategy=REALM_FILE \
-Dkeycloak.migration.file=/tmp/trikora-realm.json \
-Dkeycloak.profile.feature.upload_scripts=enabled \
-Dkeycloak.profile.feature.scripts=enabled \
-Dkeycloak.migration.strategy=OVERWRITE_EXISTING
-
If you have stored the data of the project split in several files, you can merge it in a single project just by importing the files as they are a list separated by commas:
-Dkeycloak.import=/tmp/realm1.json,/tmp/realm2.json
Warning
|
You cannot use the keycloak.import parameter with keycloak.migration.X parameters. If you use these parameters together, keycloak.import parameter will be ignored. The keycloak.import mechanism ignores the realms which already exist in the project. The keycloak.import mechanism is convenient for development purposes, but if more flexibility is needed, use the keycloak.migration.X parameters. |
Keycloak allows the user to interact with the system from an OpenID connection which is based on REST, you can see a list of the different endpoints here:
https://localhost:<CONSOLE_PORT>/auth/realms/<REALM_NAME>/.well-known/openid-configuration
In our application it would be:
https://localhost:8543/auth/realms/trikorasolutions/.well-known/openid-configuration
Import and Export:
Keycloak CRUD:
Similar Keycloaks open projects:
Problem
FATAL [org.keycloak.services] (ServerService Thread Pool -- 58) Error during startup: java.lang.RuntimeException: java.io.FileNotFoundException: /tmp/trikora-realm.json (Permission denied)
Cause
The pod has not enough permissions for accessing the realm.json file.
Solution
When running the pod, you should add the --security-opt label=disable
flag.
Problem
07:37:13,702 WARN [org.keycloak.services] (ServerService Thread Pool -- 68) KC-SERVICES0005: Unable to import realm trikorasolutions from file /tmp/trikora-realm.json.: java.lang.RuntimeException: Script upload is disabled
at [email protected]//org.keycloak.authorization.policy.provider.js.JSPolicyProviderFactory.updatePolicy(JSPolicyProviderFactory.java:125)
at [email protected]//org.keycloak.authorization.policy.provider.js.JSPolicyProviderFactory.onImport(JSPolicyProviderFactory.java:70)
Cause
From keycloak version 7.0.1 onwards, it is not possible to import a realm.json file since it is considered a deprecated way.
Solution
Adding the flag "-e -Dkeycloak.profile.feature.upload_scripts=enabled" does not work, so the only solution is to run podman with an empty master realm and then
import ours from the command line.
Other possible solution to try would be launch keycloak in version 6.0.0 with the realm and then update keycloak.
Or using: https://www.keycloak.org/docs/latest/server_development/#_script_providers
GET LIST OF REALMS FROM KC
curl -s -X GET 'http://localhost:8090/auth/admin/realms' \
-H "Accept: application/json" \
-H "Authorization: Bearer $TKN" | jq .
[
{
"id": "trikorasolutions",
"realm": "trikorasolutions",
"notBefore": 0,
"defaultSignatureAlgorithm": "RS256",
"revokeRefreshToken": false,
"refreshTokenMaxReuse": 0,
"accessTokenLifespan": 300,
"accessTokenLifespanForImplicitFlow": 900,
"ssoSessionIdleTimeout": 1800,
"ssoSessionMaxLifespan": 36000,
"ssoSessionIdleTimeoutRememberMe": 0,
"ssoSessionMaxLifespanRememberMe": 0,
"offlineSessionIdleTimeout": 2592000,
"offlineSessionMaxLifespanEnabled": false,
"offlineSessionMaxLifespan": 5184000,
"clientSessionIdleTimeout": 0,
"clientSessionMaxLifespan": 0,
"clientOfflineSessionIdleTimeout": 0,
"clientOfflineSessionMaxLifespan": 0,
"accessCodeLifespan": 60,
"accessCodeLifespanUserAction": 300,
"accessCodeLifespanLogin": 1800,
"actionTokenGeneratedByAdminLifespan": 43200,
"actionTokenGeneratedByUserLifespan": 300,
"oauth2DeviceCodeLifespan": 600,
"oauth2DevicePollingInterval": 5,
"enabled": true,
"sslRequired": "external",
"registrationAllowed": false,
"registrationEmailAsUsername": false,
"rememberMe": false,
"verifyEmail": false,
"loginWithEmailAllowed": true,
"duplicateEmailsAllowed": false,
"resetPasswordAllowed": false,
"editUsernameAllowed": false,
"bruteForceProtected": false,
"permanentLockout": false,
"maxFailureWaitSeconds": 900,
"minimumQuickLoginWaitSeconds": 60,
"waitIncrementSeconds": 60,
"quickLoginCheckMilliSeconds": 1000,
"maxDeltaTimeSeconds": 43200,
"failureFactor": 30,
"defaultRole": {
"id": "ea65e50f-5781-495c-8def-2ae818761aba",
"name": "default-roles-trikorasolutions",
"description": "${role_default-roles}",
"composite": true,
"clientRole": false,
"containerId": "trikorasolutions"
},
"requiredCredentials": [
"password"
],
"otpPolicyType": "totp",
"otpPolicyAlgorithm": "HmacSHA1",
"otpPolicyInitialCounter": 0,
"otpPolicyDigits": 6,
"otpPolicyLookAheadWindow": 1,
"otpPolicyPeriod": 30,
"otpSupportedApplications": [
"FreeOTP",
"Google Authenticator"
],
"webAuthnPolicyRpEntityName": "keycloak",
"webAuthnPolicySignatureAlgorithms": [
"ES256"
],
"webAuthnPolicyRpId": "",
"webAuthnPolicyAttestationConveyancePreference": "not specified",
"webAuthnPolicyAuthenticatorAttachment": "not specified",
"webAuthnPolicyRequireResidentKey": "not specified",
"webAuthnPolicyUserVerificationRequirement": "not specified",
"webAuthnPolicyCreateTimeout": 0,
"webAuthnPolicyAvoidSameAuthenticatorRegister": false,
"webAuthnPolicyAcceptableAaguids": [],
"webAuthnPolicyPasswordlessRpEntityName": "keycloak",
"webAuthnPolicyPasswordlessSignatureAlgorithms": [
"ES256"
],
"webAuthnPolicyPasswordlessRpId": "",
"webAuthnPolicyPasswordlessAttestationConveyancePreference": "not specified",
"webAuthnPolicyPasswordlessAuthenticatorAttachment": "not specified",
"webAuthnPolicyPasswordlessRequireResidentKey": "not specified",
"webAuthnPolicyPasswordlessUserVerificationRequirement": "not specified",
"webAuthnPolicyPasswordlessCreateTimeout": 0,
"webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister": false,
"webAuthnPolicyPasswordlessAcceptableAaguids": [],
"browserSecurityHeaders": {
"contentSecurityPolicyReportOnly": "",
"xContentTypeOptions": "nosniff",
"xRobotsTag": "none",
"xFrameOptions": "SAMEORIGIN",
"contentSecurityPolicy": "frame-src 'self'; frame-ancestors 'self'; object-src 'none';",
"xXSSProtection": "1; mode=block",
"strictTransportSecurity": "max-age=31536000; includeSubDomains"
},
"smtpServer": {},
"eventsEnabled": false,
"eventsListeners": [
"jboss-logging"
],
"enabledEventTypes": [],
"adminEventsEnabled": false,
"adminEventsDetailsEnabled": false,
"identityProviders": [],
"identityProviderMappers": [],
"internationalizationEnabled": false,
"supportedLocales": [],
"browserFlow": "browser",
"registrationFlow": "registration",
"directGrantFlow": "direct grant",
"resetCredentialsFlow": "reset credentials",
"clientAuthenticationFlow": "clients",
"dockerAuthenticationFlow": "docker auth",
"attributes": {
"cibaBackchannelTokenDeliveryMode": "poll",
"cibaExpiresIn": "120",
"cibaAuthRequestedUserHint": "login_hint",
"oauth2DeviceCodeLifespan": "600",
"clientOfflineSessionMaxLifespan": "0",
"oauth2DevicePollingInterval": "5",
"clientSessionIdleTimeout": "0",
"userProfileEnabled": "false",
"clientSessionMaxLifespan": "0",
"parRequestUriLifespan": "60",
"clientOfflineSessionIdleTimeout": "0",
"cibaInterval": "5"
},
"userManagedAccessAllowed": true,
"clientProfiles": {
"profiles": []
},
"clientPolicies": {
"policies": []
}
}
]
*GET ROLE INFO* [source, shell script]
curl -s -X GET \
'http://localhost:8090/auth/admin/realms/trikorasolutions/roles/project_manager' \
-H "Accept: application/json" \
-H "Authorization: Bearer ${TKN}" | jq .
{
"id": "bdac009e-d4d3-41be-825f-23bded18c65c",
"name": "project_manager",
"description": "Project Manager",
"composite": false,
"clientRole": false,
"containerId": "trikorasolutions",
"attributes": {}
}
*GET USERS WITH ROLE* [source, shell script]
curl -s -X GET \
'http://localhost:8090/auth/admin/realms/trikorasolutions/roles/hr/users' \
-H "Accept: application/json" \
-H "Authorization: Bearer ${TKN}" | jq .
[
{
"id": "bf3e264c-ec53-461c-ab90-e9a5c9a45bb1",
"createdTimestamp": 1635501809038,
"username": "tenant_admin_test",
"enabled": true,
"totp": false,
"emailVerified": false,
"firstName": "Test Tenant",
"lastName": "Tenant Administrator",
"email": "[email protected]",
"disableableCredentialTypes": [],
"requiredActions": [],
"notBefore": 0
}
]
*GET GROUPS WITH ROLE* [source,bash]
$ curl -s -X GET \
'http://localhost:8090/auth/admin/realms/trikorasolutions/roles/project_manager/groups' \
-H "Accept: application/json" \
-H "Authorization: Bearer ${TKN}" | jq .
[source,json]
[
{
"id": "1445ea0b-8ad7-4259-b2e5-effbfb2905bc",
"name": "Project Manager",
"path": "/Project Manager"
}
]
*GET ASSIGNED ROLES OF ONE USER* [source, shell script]
curl -s -X GET \
'http://localhost:8090/auth/admin/realms/trikorasolutions/users/ca399bfe-2e43-4891-9fef-cec854ec29fa/role-mappings/realm' \
-H "Accept: application/json" \
-H "Authorization: Bearer ${TKN}" | jq .
[
{
"id": "ea65e50f-5781-495c-8def-2ae818761aba",
"name": "default-roles-trikorasolutions",
"description": "${role_default-roles}",
"composite": true,
"clientRole": false,
"containerId": "trikorasolutions"
}
]
*GET EFFECTIVE ROLES OF ONE USER* [source, shell script]
curl -s -X GET \
'http://localhost:8090/auth/admin/realms/trikorasolutions/users/ca399bfe-2e43-4891-9fef-cec854ec29fa/role-mappings/realm/composite' \
-H "Accept: application/json" \
-H "Authorization: Bearer ${TKN}" | jq .
[
{
"id": "f7276140-abe0-4374-8e5e-1808b1053491",
"name": "uma_authorization",
"description": "${role_uma_authorization}",
"composite": false,
"clientRole": false,
"containerId": "trikorasolutions"
},
{
"id": "66e8cfbf-a28a-4034-a228-549ba14a5b92",
"name": "offline_access",
"description": "${role_offline-access}",
"composite": false,
"clientRole": false,
"containerId": "trikorasolutions"
},
{
"id": "e1f8a8b8-180f-41df-bffe-23fa24322928",
"name": "tenant_administrator",
"description": "Tenant Administrator",
"composite": false,
"clientRole": false,
"containerId": "trikorasolutions"
},
{
"id": "d8feee60-a667-41ef-b892-5eea894a611c",
"name": "user",
"composite": false,
"clientRole": false,
"containerId": "trikorasolutions"
},
{
"id": "5e09c398-7675-4876-8b4b-a426c0477b6d",
"name": "space_manager",
"description": "Space Manager",
"composite": false,
"clientRole": false,
"containerId": "trikorasolutions"
},
{
"id": "c8b91fde-84c5-43ac-b178-866e41623776",
"name": "asset_mgr",
"description": "Asset Manager",
"composite": false,
"clientRole": false,
"containerId": "trikorasolutions"
},
{
"id": "ea65e50f-5781-495c-8def-2ae818761aba",
"name": "default-roles-trikorasolutions",
"description": "${role_default-roles}",
"composite": true,
"clientRole": false,
"containerId": "trikorasolutions"
},
{
"id": "cb7ef5d2-060e-4efb-b203-7c9700312a26",
"name": "application_user",
"description": "User of the Trikora Workplace Manager application",
"composite": false,
"clientRole": false,
"containerId": "trikorasolutions"
},
{
"id": "970e4b22-23fb-4d01-904f-4b1be26f4e9e",
"name": "hr",
"description": "Human Resources",
"composite": false,
"clientRole": false,
"containerId": "trikorasolutions"
},
{
"id": "bdac009e-d4d3-41be-825f-23bded18c65c",
"name": "project_manager",
"description": "Project Manager",
"composite": false,
"clientRole": false,
"containerId": "trikorasolutions"
}
]
*GET ASSIGNED ROLES OF ONE GROUP* [source, shell script]
curl -s -X GET \
'http://localhost:8090/auth/admin/realms/trikorasolutions/groups/1445ea0b-8ad7-4259-b2e5-effbfb2905bc/role-mappings/realm' \
-H "Accept: application/json" \
-H "Authorization: Bearer ${TKN}" | jq .
[
{
"id": "cb7ef5d2-060e-4efb-b203-7c9700312a26",
"name": "application_user",
"description": "User of the Trikora Workplace Manager application",
"composite": false,
"clientRole": false,
"containerId": "trikorasolutions"
},
{
"id": "bdac009e-d4d3-41be-825f-23bded18c65c",
"name": "project_manager",
"description": "Project Manager",
"composite": false,
"clientRole": false,
"containerId": "trikorasolutions"
}
]
*GET EFFECTIVE ROLES OF ONE GROUP* [source, shell script]
curl -s -X GET \
'http://localhost:8090/auth/admin/realms/trikorasolutions/groups/1445ea0b-8ad7-4259-b2e5-effbfb2905bc/role-mappings/realm/composite' \
-H "Accept: application/json" \
-H "Authorization: Bearer ${TKN}" | jq .
[
{
"id": "cb7ef5d2-060e-4efb-b203-7c9700312a26",
"name": "application_user",
"description": "User of the Trikora Workplace Manager application",
"composite": false,
"clientRole": false,
"containerId": "trikorasolutions"
},
{
"id": "bdac009e-d4d3-41be-825f-23bded18c65c",
"name": "project_manager",
"description": "Project Manager",
"composite": false,
"clientRole": false,
"containerId": "trikorasolutions"
}
]
*GET USER BY ID* [source, shell script]
curl -s -X GET 'http://localhost:8090/auth/admin/realms/trikorasolutions/users/ca399bfe-2e43-4891-9fef-cec854ec29fa' \
-H "Accept: application/json" \
-H "Authorization: Bearer ${TKN}" | jq .
{
"id": "ca399bfe-2e43-4891-9fef-cec854ec29fa",
"createdTimestamp": 1648203035796,
"username": "pm@test",
"enabled": true,
"totp": false,
"emailVerified": false,
"firstName": "PM",
"lastName": "Test",
"email": "pm@test",
"disableableCredentialTypes": [],
"requiredActions": [],
"notBefore": 0,
"access": {
"manageGroupMembership": true,
"view": true,
"mapRoles": true,
"impersonate": true,
"manage": true
}
}
*CREATE REALM ROLE* [source, bash]
curl -X POST "http://localhost:8090/auth/admin/realms/trikorasolutions/roles" -H "Content-Type: application/json" -H "Authorization: Bearer ${TKN}" -d '{"name": "test-role2"}' | jq .
*GET REALM ROLE INFO* [source, bash]
curl -X GET "http://localhost:8090/auth/admin/realms/trikorasolutions/roles/test-role2" -H "Content-Type: application/json" -H "Authorization: Bearer ${TKN}" | jq .
[source, json]
{
"id": "6cd2efd1-2900-416d-b6ce-0f026e95c13a",
"name": "test-role2",
"composite": false,
"clientRole": false,
"containerId": "trikorasolutions",
"attributes": {}
}
ADD ROLE TO GROUPS
curl -s -X POST \
'http://localhost:8090/auth/admin/realms/trikorasolutions/groups/1445ea0b-8ad7-4259-b2e5-effbfb2905bc/role-mappings/realm' \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${TKN}" \
-d '[{"id": "cb7ef5d2-060e-4efb-b203-7c9700312a26","name": "application_user"}]' | jq .
(Empty Response)
UPDATE REALM ROLE
curl -X POST "http://localhost:8090/auth/admin/realms/trikorasolutions/roles/test-role2" -H "Content-Type: application/json" -H "Authorization: Bearer ${TKN}" -d '{"name": "test-role2"}' | jq .
DELETE REALM ROLE
curl -X DELETE "http://localhost:8090/auth/admin/realms/trikorasolutions/roles/test-role2" -H "Content-Type: application/json" -H "Authorization: Bearer ${TKN}" | jq .
(example with different credential types)
https://www.appsdeveloperblog.com/oauth-2-implicit-grant-type-flow-example/
Get what you need using sed (in this examples we are using the jq formatter, but it requires installation):
TOKEN=`echo $RESULT | sed 's/.*access_token":"//g' | sed 's/".*//g'`
SEE KEYCLOAK KEYS
curl -s -L -X GET 'http://localhost:8090/auth/realms/trikorasolutions/protocol/openid-connect/certs' | jq
{
"keys": [
{
"kid": "JyXI9mk21U9-dtqOMiizpcx1CXBi2mdxVCMwVAWgtQI",
"kty": "RSA",
"alg": "RS256",
"use": "enc",
"n": "jTDua4sKrcLXuNGa9Z3a4hJz4r8Cf07bU_6DTsqVO9mSouUNYNAsZZtaa9Ih5LEudX_vdzhP8yxjm45IDKFBymSJWczh9jNRZryz7bfM4XBnr2keFTqS1ACJSs7C4d-DdNkt5X3C6rjdf-Sxvk7i9m1KGCUV1NGsgQxakdZ_c_qi9VTDGgVXVTx6mr59OMBKvH3JJtkxT4iF0LT9JHu9XhEgWPWJS44o4appDKth9Yo5pDdk7QFB9KB_SFqmTYbQZfyLJsZ_k4mAp83y524jM0TM7HTR7BfxlchbYnTyesSb16FTW2jIMlzI0QGzMQzEiUYg2oKHpOX2w-skSQmqVw",
"e": "AQAB",
"x5c": [
"MIICrzCCAZcCBgF8MUXExTANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDDBB0cmlrb3Jhc29sdXRpb25zMB4XDTIxMDkyOTExMTUyOFoXDTMxMDkyOTExMTcwOFowGzEZMBcGA1UEAwwQdHJpa29yYXNvbHV0aW9uczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAI0w7muLCq3C17jRmvWd2uISc+K/An9O21P+g07KlTvZkqLlDWDQLGWbWmvSIeSxLnV/73c4T/MsY5uOSAyhQcpkiVnM4fYzUWa8s+23zOFwZ69pHhU6ktQAiUrOwuHfg3TZLeV9wuq43X/ksb5O4vZtShglFdTRrIEMWpHWf3P6ovVUwxoFV1U8epq+fTjASrx9ySbZMU+IhdC0/SR7vV4RIFj1iUuOKOGqaQyrYfWKOaQ3ZO0BQfSgf0hapk2G0GX8iybGf5OJgKfN8uduIzNEzOx00ewX8ZXIW2J08nrEm9ehU1toyDJcyNEBszEMxIlGINqCh6Tl9sPrJEkJqlcCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAZcZQUbP1aFyn6+sj3FiVXu61OQyZ0D+xKMpFs2H3NnciAhbR54TKcuLLkpbjgkKnXJfKvnpeAVJsy03LJ/jjm8y9RJ5nau8tTIN4u9gdnt1EuCnlsuixuTPcHSG/0VOm3hLbTgMBHHR9Z+AwEpd02e/TeKufsZhKwq5zdQ83U2xfnSzKiPNSMPx3KFVwQ1hgye5aPFsqjrVeQ2mPb5lTiOsa9XWjBms4iNS0QVr3DL3SPW2U7CsuL+N+HdtQInz+liPGh+wxJI4SS0hJLWiXnM4/Z6jBB8k2UZOglM6qVmGvXiSHY5dXME7tt8kyZ7goXnVnI0mfsiy5vhAwCVDr7g=="
],
"x5t": "QyVQnp3rRR2dz5xd7-gdkuz5yus",
"x5t#S256": "QOoAblPMbWed-kgrPQ0HF7eOuq9C_P2M8z_aMALeQ40"
},
{
"kid": "e4uF0w1q91Hum3puqqlaEEbTwtZp-TggrM-a495Y_zs",
"kty": "RSA",
"alg": "RS256",
"use": "sig",
"n": "m6l-JuPQa39k9t2Of4VVkm-ZdKp9bBdO-eMtDDq1lZ6euyZ0fyxopQDiOYfmwYCW7HINFC6k7sBRI_XIU37OVMjwhdLmcDcLiMECTk104DQzC-DLXzdnllHlj_wHOHcE-bQIK1upUmrTWNd7-A9OLCF-Izc7bW3QG3BqZ5N_wUaI6MWTcEEvSCvrGEcK17Idt_sQkIHzdVA2lgQjlPJCalS-zaSLbXcKqV04CDBdDAfbznkHcdAzVzAabi0nkj--sO9YyIKtP72jEEOeRGk0sRWPhS8n5u9JpO23uRyfGv8V0XPOlZH1F7zL2B_V5mpXDnTl4rG3ClahJ3EGx3Mo0Q",
"e": "AQAB",
"x5c": [
"MIICrzCCAZcCBgF8MUXENzANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDDBB0cmlrb3Jhc29sdXRpb25zMB4XDTIxMDkyOTExMTUyOFoXDTMxMDkyOTExMTcwOFowGzEZMBcGA1UEAwwQdHJpa29yYXNvbHV0aW9uczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJupfibj0Gt/ZPbdjn+FVZJvmXSqfWwXTvnjLQw6tZWenrsmdH8saKUA4jmH5sGAluxyDRQupO7AUSP1yFN+zlTI8IXS5nA3C4jBAk5NdOA0Mwvgy183Z5ZR5Y/8Bzh3BPm0CCtbqVJq01jXe/gPTiwhfiM3O21t0BtwameTf8FGiOjFk3BBL0gr6xhHCteyHbf7EJCB83VQNpYEI5TyQmpUvs2ki213CqldOAgwXQwH2855B3HQM1cwGm4tJ5I/vrDvWMiCrT+9oxBDnkRpNLEVj4UvJ+bvSaTtt7kcnxr/FdFzzpWR9Re8y9gf1eZqVw505eKxtwpWoSdxBsdzKNECAwEAATANBgkqhkiG9w0BAQsFAAOCAQEATZH1vrb8BqkdOSpAlo+pKTop1ga7T+wVzSqP0wzJaTJuEH7dPsnoZFUzSqczCMHetd0nJOlPECxK7ELyRKJBZAg1jFvfWfOZp+f2bcGgDOp2yCkm+fvz2Elmk5PuafMKOk0kvIFUW/Fn02DJeLEfxwZPpLkncC9ub/qCAYHQHFdWqZAhVDEd5wa7LpQdS2GOgPIBv73Qxht2xNrsqz8gRhKVhsTAIQUFXUd8a+j18YtRtE0w7hq54XilKHYuZJu8GvnlRq2zuw0T/mbWI2Imt0PPT00R0ZEesv+ha01JIxlEXuCZzIjA+CZO7/ghhRThlT+hy/nduxtw2VclD0ZtFA=="
],
"x5t": "oEHbwL2cDCYhIZxTcM-HDl6fwtA",
"x5t#S256": "Ed5UtMBRJIIFPQ8lkMU1mcJSDSDMcbpFgKbXSiQwzls"
}
]
}
curl -s -X POST 'http://localhost:8090/auth/realms/trikorasolutions/protocol/openid-connect/token' \
-H "Content-Type: application/x-www-form-urlencoded" \
-d 'client_secret=6e521ebe-e300-450f-811a-a08adc42ec4a' \
-d 'grant_type=client_credentials' \
-d 'client_id=backend-service' | jq
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlNHVGMHcxcTkxSHVtM3B1cXFsYUVFYlR3dFpwLVRnZ3JNLWE0OTVZX3pzIn0.eyJleHAiOjE2NTE3NDg1MzAsImlhdCI6MTY1MTc0ODIzMCwianRpIjoiNTUzYjkwMTYtOGVhYS00NGVhLWE1YzUtZmFlYmM1MGNjMzZmIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDkwL2F1dGgvcmVhbG1zL3RyaWtvcmFzb2x1dGlvbnMiLCJhdWQiOlsicmVhbG0tbWFuYWdlbWVudCIsImFjY291bnQiXSwic3ViIjoiN2RkNWIzODMtZDc3NS00NjdjLWE2M2ItNTU1ZDZiYjk4MmZjIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoiYmFja2VuZC1zZXJ2aWNlIiwiYWNyIjoiMSIsImFsbG93ZWQtb3JpZ2lucyI6WyIiLCJodHRwOi8vMTkyLjE2OC4xLjI0Mzo0MjAwIiwiaHR0cDovLzEwLjQyLjAuMTo0MjAwIiwiaHR0cDovL2xvY2FsaG9zdDo0MjAwIl0sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJvZmZsaW5lX2FjY2VzcyIsImRlZmF1bHQtcm9sZXMtdHJpa29yYXNvbHV0aW9ucyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsicmVhbG0tbWFuYWdlbWVudCI6eyJyb2xlcyI6WyJ2aWV3LWlkZW50aXR5LXByb3ZpZGVycyIsInZpZXctcmVhbG0iLCJtYW5hZ2UtaWRlbnRpdHktcHJvdmlkZXJzIiwiaW1wZXJzb25hdGlvbiIsInJlYWxtLWFkbWluIiwiY3JlYXRlLWNsaWVudCIsIm1hbmFnZS11c2VycyIsInF1ZXJ5LXJlYWxtcyIsInZpZXctYXV0aG9yaXphdGlvbiIsInF1ZXJ5LWNsaWVudHMiLCJxdWVyeS11c2VycyIsIm1hbmFnZS1ldmVudHMiLCJtYW5hZ2UtcmVhbG0iLCJ2aWV3LWV2ZW50cyIsInZpZXctdXNlcnMiLCJ2aWV3LWNsaWVudHMiLCJtYW5hZ2UtYXV0aG9yaXphdGlvbiIsIm1hbmFnZS1jbGllbnRzIiwicXVlcnktZ3JvdXBzIl19LCJiYWNrZW5kLXNlcnZpY2UiOnsicm9sZXMiOlsidW1hX3Byb3RlY3Rpb24iXX0sImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJtYW5hZ2UtYWNjb3VudC1saW5rcyIsInZpZXctcHJvZmlsZSJdfX0sInNjb3BlIjoicHJvZmlsZSBlbWFpbCIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwiY2xpZW50SG9zdCI6IjEwLjAuMi4xMDAiLCJjbGllbnRJZCI6ImJhY2tlbmQtc2VydmljZSIsInByZWZlcnJlZF91c2VybmFtZSI6InNlcnZpY2UtYWNjb3VudC1iYWNrZW5kLXNlcnZpY2UiLCJjbGllbnRBZGRyZXNzIjoiMTAuMC4yLjEwMCJ9.TBjM3pjES9EYxmEIVwYHSYkDO-mfQS-VVJ7jNsIHvfSA4w-692ZnugSnCb0Usn7BJUyPPQketboL_1Sy9BkTlbQEpRItN3H7USRqAJoao7So51SmOg7bx8uLx_wh0Ic2cBHcAPUJ47-XrXYLEa5EQ0FdumfC1tj-UmvM6HO-uqFh8EMO01hZZOmVFQfgzFI_7e_ZegzOTlbDxInlbDq_IOIieYQIBro8sarP-AXbD8jFtXmW1eJVI-fm_Zmbp5xrnubzEXf5ELOs-BbhYq0klGzFQUQ6OmBBQiY9ztoXfnS24JzDz41I3Otrq2mcWlfYbo9mZEvjfiUowVEcOwdprA",
"expires_in": 300,
"refresh_expires_in": 0,
"token_type": "Bearer",
"not-before-policy": 0,
"scope": "profile email"
}
GET SYSTEM ACCESS TOKEN (it is possible to select a scope with -d param)
export TKN=$(curl -s -X POST 'http://localhost:8090/auth/realms/trikorasolutions/protocol/openid-connect/token' \
-H "Content-Type: application/x-www-form-urlencoded" \
-d 'client_secret=6e521ebe-e300-450f-811a-a08adc42ec4a' \
-d 'grant_type=client_credentials' \
-d 'client_id=backend-service' | jq -r '.access_token')
This error means that the token that you are providing to Keycloak has expired or is invalid,
you can decode your token in the jwt web page: https://jwt.io/