mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2025-06-28 13:15:32 +02:00
Added SSH Public Key Logic for keycloak
This commit is contained in:
parent
b3e82fa457
commit
d815b9ee62
@ -21,4 +21,4 @@ galaxy_info:
|
||||
class: "fa-solid fa-lock"
|
||||
run_after:
|
||||
- docker-matomo
|
||||
dependencies: []
|
||||
- docker-ldap
|
||||
|
82
roles/docker-keycloak/tasks/attributes/ssh_public_key.yml
Normal file
82
roles/docker-keycloak/tasks/attributes/ssh_public_key.yml
Normal file
@ -0,0 +1,82 @@
|
||||
- name: "Wait until Keycloak is reachable at {{ keycloak_server_host_url }}"
|
||||
uri:
|
||||
url: "{{ keycloak_server_host_url }}/realms/master"
|
||||
method: GET
|
||||
status_code: 200
|
||||
validate_certs: false
|
||||
register: keycloak_check
|
||||
retries: 30
|
||||
delay: 5
|
||||
until: keycloak_check.status == 200
|
||||
|
||||
# Configure Credentials
|
||||
- name: Ensure Keycloak CLI credentials are configured
|
||||
shell: |
|
||||
{{ keycloak_kcadm_path }} config credentials \
|
||||
--server {{ keycloak_server_internal_url }} \
|
||||
--realm master \
|
||||
--user {{ keycloak_administrator_username }} \
|
||||
--password {{ keycloak_administrator_password }}
|
||||
|
||||
# LDAP Source
|
||||
- name: Get ID of LDAP storage provider
|
||||
shell: |
|
||||
{{ keycloak_kcadm_path }} get components \
|
||||
-r {{ keycloak_realm }} \
|
||||
--query 'providerId=ldap' \
|
||||
--fields id,name \
|
||||
--format json
|
||||
register: ldap_components
|
||||
|
||||
- name: Extract LDAP component ID
|
||||
set_fact:
|
||||
ldap_component_id: "{{ (ldap_components.stdout | from_json)[0].id }}"
|
||||
|
||||
- name: Ensure {{ ldap.attributes.ssh_public_key }} LDAP Mapper exists
|
||||
shell: |
|
||||
docker exec -i keycloak_application bash -c '
|
||||
/opt/keycloak/bin/kcadm.sh get components -r {{ keycloak_realm }} \
|
||||
| grep -q "\"name\" : \"{{ ldap.attributes.ssh_public_key }}\"" \
|
||||
|| printf "%s\n" "{
|
||||
\"name\": \"{{ ldap.attributes.ssh_public_key }}\",
|
||||
\"parentId\": \"{{ ldap_component_id }}\",
|
||||
\"providerId\": \"user-attribute-ldap-mapper\",
|
||||
\"providerType\": \"org.keycloak.storage.ldap.mappers.LDAPStorageMapper\",
|
||||
\"config\": {
|
||||
\"user.model.attribute\": [\"{{ ldap.attributes.ssh_public_key }}\"],
|
||||
\"ldap.attribute\": [\"{{ ldap.attributes.ssh_public_key }}\"],
|
||||
\"read.only\": [\"false\"],
|
||||
\"write.only\": [\"true\"],
|
||||
\"always.read.value.from.ldap\": [\"false\"],
|
||||
\"multivalued\": [\"true\"]
|
||||
}
|
||||
}" | /opt/keycloak/bin/kcadm.sh create components -r {{ keycloak_realm }} -f -'
|
||||
register: mapper_create
|
||||
changed_when: mapper_create.rc == 0 and mapper_create.stdout != ""
|
||||
|
||||
# GUI
|
||||
|
||||
- name: Enable user profile in realm
|
||||
shell: >
|
||||
{{ keycloak_kcadm_path }} update realms/{{ keycloak_realm }}
|
||||
-s 'attributes.userProfileEnabled=true'
|
||||
|
||||
- name: Re-authenticate to Keycloak after enabling user profile
|
||||
shell: |
|
||||
{{ keycloak_kcadm_path }} config credentials \
|
||||
--server {{ keycloak_server_internal_url }} \
|
||||
--realm master \
|
||||
--user {{ keycloak_administrator_username }} \
|
||||
--password {{ keycloak_administrator_password }}
|
||||
|
||||
- name: Render user-profile JSON for SSH key
|
||||
template:
|
||||
src: import/user-profile.json.j2
|
||||
dest: "{{ import_directory_host }}/user-profile.json"
|
||||
mode: '0644'
|
||||
notify: docker compose up
|
||||
|
||||
- name: Apply SSH Public Key to user-profile via kcadm
|
||||
shell: |
|
||||
docker exec -i {{ container_name }} \
|
||||
/opt/keycloak/bin/kcadm.sh update realms/{{ keycloak_realm }} -f {{ import_directory_docker }}user-profile.json
|
@ -25,3 +25,7 @@
|
||||
mode: '770'
|
||||
loop: "{{ lookup('fileglob', '{{ role_path }}/templates/import/*.j2', wantlist=True) }}"
|
||||
notify: docker compose up
|
||||
|
||||
# Deactivated temporary. Import now via realm.yml
|
||||
#- name: Implement SSH Public Key Attribut
|
||||
# include_tasks: attributes/ssh_public_key.yml
|
@ -8,7 +8,7 @@ services:
|
||||
command: start {% if applications[application_id].import_realm | bool %}--import-realm{% endif %}
|
||||
{% include 'roles/docker-compose/templates/services/base.yml.j2' %}
|
||||
ports:
|
||||
- "127.0.0.1:{{ports.localhost.http[application_id]}}:8080"
|
||||
- "{{ keycloak_server_host }}:8080"
|
||||
volumes:
|
||||
- "{{import_directory_host}}:{{import_directory_docker}}"
|
||||
{% include 'templates/docker/container/depends-on-just-database.yml.j2' %}
|
||||
|
@ -10,8 +10,11 @@ KC_HTTP_ENABLED= true
|
||||
KC_HEALTH_ENABLED= true
|
||||
KC_METRICS_ENABLED= true
|
||||
|
||||
# Administrator
|
||||
KEYCLOAK_ADMIN= "{{applications[application_id].users.administrator.username}}"
|
||||
KEYCLOAK_ADMIN_PASSWORD= "{{applications[application_id].credentials.administrator_password}}"
|
||||
|
||||
# Database
|
||||
KC_DB= postgres
|
||||
KC_DB_URL= {{database_url_jdbc}}
|
||||
KC_DB_USERNAME= {{database_username}}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"id": "3b03105b-5fe6-4b53-ba24-c8796525be0e",
|
||||
"realm": "{{realm}}",
|
||||
"realm": "{{ keycloak_realm }}",
|
||||
"displayName": "",
|
||||
"displayNameHtml": "",
|
||||
"notBefore": 0,
|
||||
@ -60,7 +60,7 @@
|
||||
},
|
||||
{
|
||||
"id": "01d9dd2a-75b2-47a2-af36-b14251f1b956",
|
||||
"name": "default-roles-{{realm}}",
|
||||
"name": "default-roles-{{ keycloak_realm }}",
|
||||
"description": "${role_default-roles}",
|
||||
"composite": true,
|
||||
"composites": {
|
||||
@ -302,7 +302,7 @@
|
||||
"attributes": {}
|
||||
}
|
||||
],
|
||||
"{{realm}}": [],
|
||||
"{{ keycloak_realm }}": [],
|
||||
"security-admin-console": [],
|
||||
"admin-cli": [],
|
||||
"account-console": [],
|
||||
@ -410,7 +410,7 @@
|
||||
"groups": [],
|
||||
"defaultRole": {
|
||||
"id": "01d9dd2a-75b2-47a2-af36-b14251f1b956",
|
||||
"name": "default-roles-{{realm}}",
|
||||
"name": "default-roles-{{ keycloak_realm }}",
|
||||
"description": "${role_default-roles}",
|
||||
"composite": true,
|
||||
"clientRole": false,
|
||||
@ -464,18 +464,18 @@
|
||||
"users": [
|
||||
{
|
||||
"id": "19ecedfd-acf2-49e8-9f66-91ab71d54fc3",
|
||||
"username": "service-account-{{realm}}",
|
||||
"username": "service-account-{{ keycloak_realm }}",
|
||||
"emailVerified": false,
|
||||
"createdTimestamp": 1737925519602,
|
||||
"enabled": true,
|
||||
"totp": false,
|
||||
"serviceAccountClientId": "{{realm}}",
|
||||
"serviceAccountClientId": "{{ keycloak_realm }}",
|
||||
"disableableCredentialTypes": [],
|
||||
"requiredActions": [
|
||||
"CONFIGURE_TOTP"
|
||||
],
|
||||
"realmRoles": [
|
||||
"default-roles-{{realm}}"
|
||||
"default-roles-{{ keycloak_realm }}"
|
||||
],
|
||||
"notBefore": 0,
|
||||
"groups": []
|
||||
@ -508,13 +508,13 @@
|
||||
"description": "",
|
||||
"rootUrl": "${authBaseUrl}",
|
||||
"adminUrl": "",
|
||||
"baseUrl": "/realms/{{realm}}/account/",
|
||||
"baseUrl": "/realms/{{ keycloak_realm }}/account/",
|
||||
"surrogateAuthRequired": false,
|
||||
"enabled": true,
|
||||
"alwaysDisplayInConsole": false,
|
||||
"clientAuthenticatorType": "client-secret",
|
||||
"redirectUris": [
|
||||
"/realms/{{realm}}/account/*"
|
||||
"/realms/{{ keycloak_realm }}/account/*"
|
||||
],
|
||||
"webOrigins": [
|
||||
"{{ web_protocol }}://{{domains | get_domain('keycloak')}}"
|
||||
@ -564,13 +564,13 @@
|
||||
"description": "",
|
||||
"rootUrl": "${authBaseUrl}",
|
||||
"adminUrl": "",
|
||||
"baseUrl": "/realms/{{realm}}/account/",
|
||||
"baseUrl": "/realms/{{ keycloak_realm }}/account/",
|
||||
"surrogateAuthRequired": false,
|
||||
"enabled": true,
|
||||
"alwaysDisplayInConsole": false,
|
||||
"clientAuthenticatorType": "client-secret",
|
||||
"redirectUris": [
|
||||
"/realms/{{realm}}/account/*"
|
||||
"/realms/{{ keycloak_realm }}/account/*"
|
||||
],
|
||||
"webOrigins": [
|
||||
"*"
|
||||
@ -756,13 +756,13 @@
|
||||
"clientId": "security-admin-console",
|
||||
"name": "${client_security-admin-console}",
|
||||
"rootUrl": "${authAdminUrl}",
|
||||
"baseUrl": "/admin/{{realm}}/console/",
|
||||
"baseUrl": "/admin/{{ keycloak_realm }}/console/",
|
||||
"surrogateAuthRequired": false,
|
||||
"enabled": true,
|
||||
"alwaysDisplayInConsole": false,
|
||||
"clientAuthenticatorType": "client-secret",
|
||||
"redirectUris": [
|
||||
"/admin/{{realm}}/console/*"
|
||||
"/admin/{{ keycloak_realm }}/console/*"
|
||||
],
|
||||
"webOrigins": [
|
||||
"+"
|
||||
@ -822,12 +822,12 @@
|
||||
},
|
||||
{
|
||||
"id": "7b5f97e3-7fa8-4d86-b1e9-80aac996da26",
|
||||
"clientId": "{{realm}}",
|
||||
"clientId": "{{ keycloak_realm }}",
|
||||
"name": "",
|
||||
"description": "",
|
||||
"rootUrl": "{{ web_protocol }}://{{realm}}/",
|
||||
"adminUrl": "{{ web_protocol }}://{{realm}}/",
|
||||
"baseUrl": "{{ web_protocol }}://{{realm}}/",
|
||||
"rootUrl": "{{ web_protocol }}://{{ keycloak_realm }}/",
|
||||
"adminUrl": "{{ web_protocol }}://{{ keycloak_realm }}/",
|
||||
"baseUrl": "{{ web_protocol }}://{{ keycloak_realm }}/",
|
||||
"surrogateAuthRequired": false,
|
||||
"enabled": true,
|
||||
"alwaysDisplayInConsole": false,
|
||||
@ -1792,7 +1792,7 @@
|
||||
"subComponents": {},
|
||||
"config": {
|
||||
"kc.user.profile.config": [
|
||||
"{\"attributes\":[{\"name\":\"username\",\"displayName\":\"${username}\",\"validations\":{\"length\":{\"min\":3,\"max\":255},\"pattern\":{\"pattern\":\"^[a-z0-9]+$\",\"error-message\":\"\"}},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"email\",\"displayName\":\"${email}\",\"validations\":{\"email\":{},\"length\":{\"max\":255}},\"required\":{\"roles\":[\"user\"]},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"firstName\",\"displayName\":\"${firstName}\",\"validations\":{\"length\":{\"max\":255},\"person-name-prohibited-characters\":{}},\"required\":{\"roles\":[\"user\"]},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"lastName\",\"displayName\":\"${lastName}\",\"validations\":{\"length\":{\"max\":255},\"person-name-prohibited-characters\":{}},\"required\":{\"roles\":[\"user\"]},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false}],\"groups\":[{\"name\":\"user-metadata\",\"displayHeader\":\"User metadata\",\"displayDescription\":\"Attributes, which refer to user metadata\"}]}"
|
||||
"{\"attributes\":[{\"name\":\"username\",\"displayName\":\"${username}\",\"validations\":{\"length\":{\"min\":3,\"max\":255},\"pattern\":{\"pattern\":\"^[a-z0-9]+$\",\"error-message\":\"\"}},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"email\",\"displayName\":\"${email}\",\"validations\":{\"email\":{},\"length\":{\"max\":255}},\"required\":{\"roles\":[\"user\"]},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"firstName\",\"displayName\":\"${firstName}\",\"validations\":{\"length\":{\"max\":255},\"person-name-prohibited-characters\":{}},\"required\":{\"roles\":[\"user\"]},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"lastName\",\"displayName\":\"${lastName}\",\"validations\":{\"length\":{\"max\":255},\"person-name-prohibited-characters\":{}},\"required\":{\"roles\":[\"user\"]},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"{{ ldap.attributes.ssh_public_key }}\",\"displayName\":\"SSH Public Key\",\"validations\":{},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"user-metadata\",\"multivalued\":true}],\"groups\":[{\"name\":\"user-metadata\",\"displayHeader\":\"User metadata\",\"displayDescription\":\"Attributes, which refer to user metadata\"}]}"
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -1977,6 +1977,35 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "24cd9c3b-e22d-4540-bddf-ae7faac0196c",
|
||||
"name": "SSH Public Key",
|
||||
"providerId": "user-attribute-ldap-mapper",
|
||||
"subComponents": {},
|
||||
"config": {
|
||||
"ldap.attribute": [
|
||||
"{{ ldap.attributes.ssh_public_key }}"
|
||||
],
|
||||
"is.mandatory.in.ldap": [
|
||||
"false"
|
||||
],
|
||||
"attribute.force.default": [
|
||||
"false"
|
||||
],
|
||||
"is.binary.attribute": [
|
||||
"false"
|
||||
],
|
||||
"read.only": [
|
||||
"false"
|
||||
],
|
||||
"always.read.value.from.ldap": [
|
||||
"true"
|
||||
],
|
||||
"user.model.attribute": [
|
||||
"{{ ldap.attributes.ssh_public_key }}"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "85cd9847-4063-4d8b-be03-fa16377cde56",
|
||||
"name": "email",
|
||||
|
@ -1,6 +1,14 @@
|
||||
application_id: "keycloak"
|
||||
database_type: "postgres"
|
||||
container_name: "{{application_id}}_application"
|
||||
realm: "{{primary_domain}}" # This is the name of the default realm which is used by the applications
|
||||
import_directory_host: "{{docker_compose.directories.volumes}}import/" # Directory in which keycloack import files are placed on the host
|
||||
import_directory_docker: "/opt/keycloak/data/import/" # Directory in which keycloack import files are placed in the running docker container
|
||||
keycloak_realm: "{{ primary_domain}}" # This is the name of the default realm which is used by the applications
|
||||
keycloak_administrator: "{{ applications[application_id].users.administrator }}" # Master Administrator
|
||||
keycloak_administrator_username: "{{ keycloak_administrator.username}}" # Master Administrator Username
|
||||
keycloak_administrator_password: "{{ keycloak_administrator.password}}" # Master Administrator Password
|
||||
keycloak_kcadm_path: "docker exec -i {{ container_name }} /opt/keycloak/bin/kcadm.sh"
|
||||
keycloak_server_internal_url: "http://127.0.0.1:8080"
|
||||
keycloak_server_host: "127.0.0.1:{{ports.localhost.http[application_id]}}"
|
||||
keycloak_server_host_url: "http://{{ keycloak_server_host }}"
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
vars:
|
||||
schema_name: "openssh-lpk"
|
||||
attribute_defs:
|
||||
- "( 1.3.6.1.4.1.24552.1.1 NAME 'sshPublicKey' DESC 'OpenSSH Public Key' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )"
|
||||
- "( 1.3.6.1.4.1.24552.1.1 NAME '{{ ldap.attributes.ssh_public_key }}' DESC 'OpenSSH Public Key' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )"
|
||||
- "( 1.3.6.1.4.1.24552.1.2 NAME 'sshFingerprint' DESC 'OpenSSH Public Key Fingerprint' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )"
|
||||
objectclass_defs:
|
||||
- >-
|
||||
@ -17,7 +17,7 @@
|
||||
DESC 'Auxiliary class for OpenSSH public keys'
|
||||
SUP top
|
||||
AUXILIARY
|
||||
MAY ( sshPublicKey $ sshFingerprint ) )
|
||||
MAY ( {{ ldap.attributes.ssh_public_key }} $ sshFingerprint ) )
|
||||
|
||||
command: >
|
||||
ldapsm
|
||||
|
Loading…
x
Reference in New Issue
Block a user