Keycloak
Keycloak provides the OAuth2 and OIDC functionalities used for this project. The controller
module uses Keycloak to
authenticate users or clients and to authorize requests. It also uses the Keycloak admin client extension to register
clients. Keycloak is deployed inside the cluster/helm/eurodat-cluster
Helm Chart, where a basic admin user
is configured, requiring only 2 environment variables (which can be written into ones .bashrc
).
The current default values are:
Controller Setup
After the initial deployment is done, different realms with necessary clients are created. The external clients are registered in
Keycloak via the controller
API.
During the client registration, one also needs to provide Keycloak a certificate that is later
used to authenticate the respective controllers. All this is currently done dynamically
in the CI/CD pipeline (see cluster/helm/.gitlab-ci.yml
& cluster/scripts
).
Keycloak administration
The registered Keycloak clients are confidential clients with the clientAuthenticatorType
set to client-jwt
.
The client certificate needed by client-jwt
is registered with a RS256
algorithm.
The clients can be configured most extensively using Keycloak's admin REST API. There are two possible ways to access the admin REST API, one is by running a bash command inside the Keycloak
Kubernetes-pod via exec <pod> -it -- bash -c <command>
, which will run the kcadm.sh
script inside the
/opt/jboss/keycloak/bin
folder. The other one is talking to it directly via curl
, which requires
Keycloak's URL and an initial access token (IAT) inside the header of the request. Currently, we only use the
second approach.
Using the Admin REST API
All Keycloak requests are handled by a central script . Run ./kc_do --help
to receive
more information about it.
- Get general help
- Get help for any command (eg. "create" = POST)
kubectl -n $NAMESPACE exec $KC_POD_NAME -it -- bash -c "./opt/jboss/keycloak/bin/kcadm.sh create --help"
Using the Keycloak UI
First deploy the eurodat-cluster
Helm Chart.
Register Client
-
Generate an Initial Access Token
- Forward Keycloak port:
- Go to
Realm Settings
>Client Registration
>Initial Access Token
>Create
- Insert values and click on
Save
-
Send a POST Request with the Initial Access Token inside the header and clientID in the body
- CURL:
Other Problems
- Do not use password made out of only numbers
Keycloak seems to think that those are integers, leading the following error:
Error: StatefulSet in version "v1" cannot be handled as a StatefulSet: v1.StatefulSet.Spec: v1.StatefulSetSpec.Template: v1.PodTemplateSpec.Spec: v1.PodSpec.Containers: []v1.Container: v1.Container.Env: []v1.EnvVar: v1.EnvVar.Value: ReadString: expects " or n, but found 1, error found in #10 byte of ...|,"value":YOUR_NUMBER_PASSWORD}]...
-
Pod name Problems
Keycloak's Helm Chart comes with the option to edit its pod and service name with thefullnameOverride
variable. However, there is a 23-character limit which, if exceeded, will lead to this being ignored. -
Client-Role mapping
Currently, we register a user for each realm who, after creation, requires an additional role-mapping to allow him to register clients inside the realm. This is done the Admin Rest API, but can also be done manually via the UI:
Users > <User> > "Role Mappings" > "Client Roles" > "realm-management" > select "manage-clients" > "Add selected"
NOTE that the correct client role is NOT create-client.
- Client-ID and Client's ID
Keycloak's clients have 2 IDs inside their ClientRepresentation , aClientId
which is basically the "username" of the client and the only ID you see in Keycloak's UI; the other one is the client's Id which, if not specified is set to a random UUID. Keycloak refers to the first asclient-id
. The client's Id is only needed when performing a GET or PUT request to Keycloak's Admin Rest API.
We set both of those IDs, where the Id is a combination of theclientId-realmName
. This is necessary because of a bug which does not allow any client to share the same Id, even those that are not in the samerealm
. - User-ID
Although Keycloak's API now allows to specify an Id in the request body for the user creation , it actually is ignored when set and a random UUID is used in its place.