Kestone SSO Support¶
Keycloak Setup¶
Configure client (keystone)¶
TODO: Add realm setup in Keycloak
TODO: Add client setup in Keycloak
How to inspect the token for a user?¶
Authentication Flows enabled in Keycloak
- Standard Flow
- Implicit Flow
- Direct Access grants
- OAuth 2.0 Device Authorization Grant
- Service accounts roles
- OIDC CIBA Grant
Warning
I'm not sure if Standard Flow is required (didn't test yet without). Also Direct Access grants is only for
testing purposes to be able to retrieve a token and inspect it.
Get a token for user john.doe@virtomat.net using client keystone by placing a direct call to /token endpoint:
curl --location --request POST 'http://auth.virtomat.net/realms/virtomat/protocol/openid-connect/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=keystone' \
--data-urlencode 'client_secret=RTzvozXr07H2PH7JcbzM3ho6RI5SrYpA' \
--data-urlencode 'username=john.doe@virtomat.net' \
--data-urlencode 'password=kYHkxe6X' \
--data-urlencode 'grant_type=password'
Response with the token (expand to see)
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ3alBhUDA3T3ZzMmxlTDVsUmc3WmVzOWpHLV9LOTRNZWpsNEJpOFA3ekNRIn0.eyJleHAiOjE3MjU0NjI0MjUsImlhdCI6MTcyNTQ2MjEyNSwianRpIjoiZTMyOGFlMWYtMzg1OS00Y2NiLWIyYTUtZjg5MGU1YjJmYzNmIiwiaXNzIjoiaHR0cHM6Ly9hdXRoLnZpcnRvbWF0Lm5ldC9yZWFsbXMvdmlydG9tYXQiLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiZDBkZmY5NzUtMTk1Ni00YzBjLTk1OTgtNzg0NmM0MDRlMTExIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoia2V5c3RvbmUiLCJzaWQiOiIzMzQyYjQ2MC1mNTBhLTQ2NTUtODA5Yy0wZTVlYzM3NzFhZWYiLCJhY3IiOiIxIiwiYWxsb3dlZC1vcmlnaW5zIjpbImh0dHBzOi8vY2xvdWQudmlydG9tYXQubmV0IiwiaHR0cHM6Ly9jbG91ZC52aXJ0b21hdC5uZXQ6NTAwMCJdLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiIsImRlZmF1bHQtcm9sZXMtdmlydG9tYXQiXX0sInJlc291cmNlX2FjY2VzcyI6eyJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6ImVtYWlsIHByb2ZpbGUiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwibmFtZSI6IkpvaG4gRG9lIiwicHJlZmVycmVkX3VzZXJuYW1lIjoiam9obi5kb2VAdmlydG9tYXQubmV0IiwiZ2l2ZW5fbmFtZSI6IkpvaG4iLCJmYW1pbHlfbmFtZSI6IkRvZSIsImVtYWlsIjoiam9obi5kb2VAdmlydG9tYXQubmV0In0.CaEPNm0607laQMViPJcVmHIXKyNbH5SzcQ8LslEgbWOX0SeyBOjffQbrsf_w7UUXUXwzOFLLLCvZVBpzLr9tfHYdWUuA63k3RzT8Mnh3V3w-sgYeZlAOg9fUzQycT6GYRujKpvlpLSar2BlUpkmZLFQzV1do74nhHAe8zRiuESsMEdVmUaOtQvcDIkS7XXEpktpiAspkn1OLv2eq8n5r__-N0Bj9fONKyROOZq5mngqMBeL60cI-Lko2EOy5hwWgkeV4kbi_RGzosIX88dCXXkyHaI_WCJpYe64YutHHDRi8NoyiQNjQSAukMr0XdMWXBwgMOUStS_ZyafnmOleG6g",
"expires_in": 300,
"refresh_expires_in": 1800,
"refresh_token": "eyJhbGciOiJIUzUxMiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJmNTg3ZDE4My01YWE4LTRiNTYtOGYxNS1mNzYxOGE1MTZlMTUifQ.eyJleHAiOjE3MjU0NjM5MjUsImlhdCI6MTcyNTQ2MjEyNSwianRpIjoiYWZlZWU2YzEtMTcyMC00NzQ3LWE3MjctY2U0MmZmZWQ1MjA0IiwiaXNzIjoiaHR0cHM6Ly9hdXRoLnZpcnRvbWF0Lm5ldC9yZWFsbXMvdmlydG9tYXQiLCJhdWQiOiJodHRwczovL2F1dGgudmlydG9tYXQubmV0L3JlYWxtcy92aXJ0b21hdCIsInN1YiI6ImQwZGZmOTc1LTE5NTYtNGMwYy05NTk4LTc4NDZjNDA0ZTExMSIsInR5cCI6IlJlZnJlc2giLCJhenAiOiJrZXlzdG9uZSIsInNpZCI6IjMzNDJiNDYwLWY1MGEtNDY1NS04MDljLTBlNWVjMzc3MWFlZiIsInNjb3BlIjoiYmFzaWMgd2ViLW9yaWdpbnMgZW1haWwgYWNyIHByb2ZpbGUgcm9sZXMifQ.pg--y1d_Tn3cU02DEhTqHp9Ebg75Ja1a8lmLud_qmALH87ue3NGSeLJTwQSDktx-fdmm9MMNClfkvArKEYKe0A",
"token_type": "Bearer",
"not-before-policy": 0,
"session_state": "3342b460-f50a-4655-809c-0e5ec3771aef",
"scope": "email profile"
}
Tip
You can then paste the token into tools like jwt.io and inspect
JWT payload data example (expand to see)
{
"exp": 1725462425,
"iat": 1725462125,
"jti": "e328ae1f-3859-4ccb-b2a5-f890e5b2fc3f",
"iss": "https://auth.virtomat.net/realms/virtomat",
"aud": "account",
"sub": "d0dff975-1956-4c0c-9598-7846c404e111",
"typ": "Bearer",
"azp": "keystone",
"sid": "3342b460-f50a-4655-809c-0e5ec3771aef",
"acr": "1",
"allowed-origins": [
"https://cloud.virtomat.net",
"https://cloud.virtomat.net:5000"
],
"realm_access": {
"roles": [
"offline_access",
"uma_authorization",
"default-roles-virtomat"
]
},
"resource_access": {
"account": {
"roles": [
"manage-account",
"manage-account-links",
"view-profile"
]
}
},
"scope": "email profile",
"email_verified": true,
"name": "John Doe",
"preferred_username": "john.doe@virtomat.net",
"given_name": "John",
"family_name": "Doe",
"email": "john.doe@virtomat.net"
}
Keystone Setup¶
External references:
Keystone Mapping Combinations (Yoga)
Configure keystone mappings
Keystone with OpenID Connect
Configure using OSA (Openstack Ansible)¶
TODO: Add git repository reference
Snippet from user_variables.yaml (expand to see)
keystone_sp:
apache_mod: 'mod_auth_openidc'
cadf_notifications: true
cadf_notifications_opt_out:
- identity.authenticate.failed
- identity.authenticate.pending
- identity.authenticate.success
trusted_dashboard_list:
- "https://{{ horizon_server_name }}/auth/websso/"
- "https://{{ external_lb_vip_address }}/auth/websso/"
trusted_idp_list:
- name: "oidc-idp"
oidc_provider_metadata_url: https://auth.virtomat.net/realms/virtomat/.well-known/openid-configuration
oidc_client_id: keystone
oidc_client_secret: RTzvozXr07H2PH7JcbzM3ho6RI5SrYpA
oidc_redirect_path: "/oidc_redirect"
oidc_crypto_passphrase: a-random-secret-used-by-apache-oidc-and-balancer-not-keycloak
oidc_auth_verify_jwks_uri: "https://auth.virtomat.net/realms/virtomat/protocol/openid-connect/certs"
domain_id: default
entity_ids:
- 'https://auth.virtomat.net/realms/virtomat'
federated_identities:
- domain: default
project: federated_project
group: federated_users
role: _member_
protocols:
- name: openid
mapping:
name: openid-mapping
rules:
- remote:
- type: OIDC-email
- type: OIDC-given_name
- type: OIDC-family_name
local:
- projects:
- name: '{1}.{2}-ws'
roles:
- name: "_member_"
- name: "load-balancer_member"
domain:
id: default
- user:
email: '{0}'
name: '{1} {2}'
domain:
id: default
TODO: Add explanation of how the rules engine works (explain the rules)
To update the mappings using openstack-ansible, once the user_variables.yaml file is configured properly, execute the playbook:
11:46 AM /opt/openstack-ansible
root@ansible-dev# openstack-ansible playbooks/os-keystone-install.yml
Configure using CLI¶
To update a particular rule using the openstack cli, you need the json equivalent of the rules object.
Rules list for a mapping in JSON format (expand to see)
[
{
"remote": [
{
"type": "OIDC-email"
},
{
"type": "OIDC-given_name"
},
{
"type": "OIDC-family_name"
}
],
"local": [
{
"projects": [
{
"name": "{1}.{2}-ws",
"roles": [
{
"name": "_member_"
},
{
"name": "load-balancer_member"
}
]
}
],
"domain": {
"id": "default"
},
"user": {
"name": "{1} {2}",
"email": "{0}",
"domain": {
"id": "default"
}
}
}
]
}
]
Assuming you have the rules json in a file called openid-mapping-rules.json we can use openstack cli to set/update:
openstack mapping set openid-mapping --rules openid-mapping-rules.json