From 06b864ad52704ee0ccdf72c69e0b8ccfdf506fbd Mon Sep 17 00:00:00 2001 From: Kevin Veen-Birkenbach Date: Fri, 4 Jul 2025 16:16:45 +0200 Subject: [PATCH] Refactored LDAP and Keycloak implementation and added RBAC based groups to Keycloak --- group_vars/all/12_oidc.yml | 4 +- group_vars/all/13_ldap.yml | 47 +++--- roles/docker-bigbluebutton/templates/env.j2 | 4 +- roles/docker-funkwhale/templates/env.j2 | 4 +- roles/docker-gitea/vars/main.yml | 10 +- .../tasks/attributes/ssh_public_key.yml | 10 +- .../templates/import/realm.json.j2 | 155 +++++++++++++++--- roles/docker-keycloak/vars/configuration.yml | 7 +- roles/docker-ldap/tasks/add_user_objects.yml | 4 +- roles/docker-ldap/tasks/main.yml | 8 +- roles/docker-ldap/tasks/schemas/nextcloud.yml | 4 +- .../docker-ldap/tasks/schemas/openssh_lpk.yml | 6 +- .../templates/config/oidc.config.php.j2 | 4 +- .../vars/plugins/user_ldap.yml | 2 +- .../templates/oauth2-proxy-keycloak.cfg.j2 | 7 +- roles/docker-openproject/vars/ldap.yml | 6 +- roles/docker-snipe-it/tasks/ldap.yml | 8 +- 17 files changed, 206 insertions(+), 84 deletions(-) diff --git a/group_vars/all/12_oidc.yml b/group_vars/all/12_oidc.yml index c5f89732..1a76df21 100644 --- a/group_vars/all/12_oidc.yml +++ b/group_vars/all/12_oidc.yml @@ -39,4 +39,6 @@ defaults_oidc: username: "preferred_username" given_name: "givenName" family_name: "surname" - email: "email" \ No newline at end of file + email: "email" + claims: + groups: "groups" diff --git a/group_vars/all/13_ldap.yml b/group_vars/all/13_ldap.yml index cc9eced9..81e7acc9 100644 --- a/group_vars/all/13_ldap.yml +++ b/group_vars/all/13_ldap.yml @@ -54,14 +54,6 @@ ldap: # – Keeping these distinct prevents accidental use of config credentials # for ordinary user/group operations, and vice versa. - attributes: - # Attribut to identify the user - user_id: "{{ _ldap_user_id }}" - mail: "mail" - fullname: "cn" - firstname: "givenname" - surname: "sn" - ssh_public_key: "sshPublicKey" # Password to access dn.bind bind_credential: "{{ applications.ldap.credentials.administrator_database_password }}" server: @@ -71,21 +63,30 @@ ldap: security: "" #TLS, SSL - Leave empty for none network: local: "{{applications.ldap.network.docker}}" # Uses the application configuration to define if local network should be available or not - user_objects: - structural: - - person # Structural Classes define the core identity of an entry: - # • Specify mandatory attributes (e.g. sn, cn) - # • Each entry must have exactly one structural class - - inetOrgPerson # An extension of person adding internet-related attributes - # (e.g. mail, employeeNumber) - - posixAccount # Provides UNIX account attributes (uidNumber, gidNumber, - # homeDirectory) - auxiliary: - - nextcloudUser # Auxiliary Classes attach optional attributes without - # changing the entry’s structural role. Here they add - # nextcloudQuota and nextcloudEnabled for Nextcloud. - - ldapPublicKey # Allows storing SSH public keys for services like Gitea. - + user: + objects: + structural: + - person # Structural Classes define the core identity of an entry: + # • Specify mandatory attributes (e.g. sn, cn) + # • Each entry must have exactly one structural class + - inetOrgPerson # An extension of person adding internet-related attributes + # (e.g. mail, employeeNumber) + - posixAccount # Provides UNIX account attributes (uidNumber, gidNumber, + # homeDirectory) + auxiliary: + nextloud_user: "nextcloudUser" # Auxiliary Classes attach optional attributes without + # changing the entry’s structural role. Here they add + # nextcloudQuota and nextcloudEnabled for Nextcloud. + ssh_public_key: "ldapPublicKey" # Allows storing SSH public keys for services like Gitea. + attributes: + # Attribut to identify the user + id: "{{ _ldap_user_id }}" + mail: "mail" + fullname: "cn" + firstname: "givenname" + surname: "sn" + ssh_public_key: "sshPublicKey" + nextcloud_quota: "nextcloudQuota" filters: users: login: "(&{{ _ldap_filters_users_all }}({{_ldap_user_id}}=%{{_ldap_user_id}}))" diff --git a/roles/docker-bigbluebutton/templates/env.j2 b/roles/docker-bigbluebutton/templates/env.j2 index 063fb833..a3241f41 100644 --- a/roles/docker-bigbluebutton/templates/env.j2 +++ b/roles/docker-bigbluebutton/templates/env.j2 @@ -170,7 +170,7 @@ OAUTH2_REDIRECT= # LDAP_SERVER=ldap.example.com # LDAP_PORT=389 # LDAP_METHOD=plain -# LDAP_UID={{ldap.attributes.user_id}} +# LDAP_UID={{ldap.user.attributes.id}} # LDAP_BASE=dc=example,dc=com # LDAP_AUTH=simple # LDAP_BIND_DN=cn=admin,dc=example,dc=com @@ -180,7 +180,7 @@ OAUTH2_REDIRECT= LDAP_SERVER="{{ldap.server.domain}}" LDAP_PORT="{{ldap.server.port}}" LDAP_METHOD= -LDAP_UID={{ldap.attributes.user_id}} +LDAP_UID={{ldap.user.attributes.id}} LDAP_BASE="{{ldap.dn.root}}" LDAP_BIND_DN="{{ldap.dn.administrator.data}}" LDAP_AUTH=password diff --git a/roles/docker-funkwhale/templates/env.j2 b/roles/docker-funkwhale/templates/env.j2 index 5b92676c..d2fcd88d 100644 --- a/roles/docker-funkwhale/templates/env.j2 +++ b/roles/docker-funkwhale/templates/env.j2 @@ -111,10 +111,10 @@ LDAP_ENABLED = True LDAP_SERVER_URI = "{{ ldap.server.uri }}" LDAP_BIND_DN = "{{ ldap.dn.administrator.data }}" LDAP_BIND_PASSWORD = "{{ ldap.bind_credential }}" -#LDAP_SEARCH_FILTER = "{{ ldap.filters.users.login | replace('%' ~ ldap.attributes.user_id, '{0}') }}" +#LDAP_SEARCH_FILTER = "{{ ldap.filters.users.login | replace('%' ~ ldap.user.attributes.id, '{0}') }}" LDAP_START_TLS = False LDAP_ROOT_DN = "{{ldap.dn.root}}" -#LDAP_USER_ATTR_MAP = "first_name:{{ ldap.attributes.firstname }}, last_name:{{ ldap.attributes.surname }}, username:{{ ldap.attributes.user_id }}, email:{{ ldap.attributes.mail }}" +#LDAP_USER_ATTR_MAP = "first_name:{{ ldap.user.attributes.firstname }}, last_name:{{ ldap.user.attributes.surname }}, username:{{ ldap.user.attributes.id }}, email:{{ ldap.user.attributes.mail }}" {% endif %} diff --git a/roles/docker-gitea/vars/main.yml b/roles/docker-gitea/vars/main.yml index 9c485d76..c254479d 100644 --- a/roles/docker-gitea/vars/main.yml +++ b/roles/docker-gitea/vars/main.yml @@ -9,9 +9,9 @@ gitea_ldap_auth_args: - '--bind-password "{{ ldap.bind_credential }}"' - '--user-search-base "{{ ldap.dn.ou.users }}"' - '--user-filter "(&(objectClass=inetOrgPerson)(uid=%s))"' - - '--username-attribute "{{ ldap.attributes.user_id }}"' - - '--firstname-attribute "{{ ldap.attributes.firstname }}"' - - '--surname-attribute "{{ ldap.attributes.surname }}"' - - '--email-attribute "{{ ldap.attributes.mail }}"' - - '--public-ssh-key-attribute "{{ ldap.attributes.ssh_public_key }}"' + - '--username-attribute "{{ ldap.user.attributes.id }}"' + - '--firstname-attribute "{{ ldap.user.attributes.firstname }}"' + - '--surname-attribute "{{ ldap.user.attributes.surname }}"' + - '--email-attribute "{{ ldap.user.attributes.mail }}"' + - '--public-ssh-key-attribute "{{ ldap.user.attributes.ssh_public_key }}"' - '--synchronize-users' diff --git a/roles/docker-keycloak/tasks/attributes/ssh_public_key.yml b/roles/docker-keycloak/tasks/attributes/ssh_public_key.yml index d0e5d5a3..84981b16 100644 --- a/roles/docker-keycloak/tasks/attributes/ssh_public_key.yml +++ b/roles/docker-keycloak/tasks/attributes/ssh_public_key.yml @@ -32,19 +32,19 @@ set_fact: ldap_component_id: "{{ (ldap_components.stdout | from_json)[0].id }}" -- name: Ensure {{ ldap.attributes.ssh_public_key }} LDAP Mapper exists +- name: Ensure {{ ldap.user.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 }}\"" \ + | grep -q "\"name\" : \"{{ ldap.user.attributes.ssh_public_key }}\"" \ || printf "%s\n" "{ - \"name\": \"{{ ldap.attributes.ssh_public_key }}\", + \"name\": \"{{ ldap.user.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 }}\"], + \"user.model.attribute\": [\"{{ ldap.user.attributes.ssh_public_key }}\"], + \"ldap.attribute\": [\"{{ ldap.user.attributes.ssh_public_key }}\"], \"read.only\": [\"false\"], \"write.only\": [\"true\"], \"always.read.value.from.ldap\": [\"false\"], diff --git a/roles/docker-keycloak/templates/import/realm.json.j2 b/roles/docker-keycloak/templates/import/realm.json.j2 index aaf0e2d7..715e8953 100644 --- a/roles/docker-keycloak/templates/import/realm.json.j2 +++ b/roles/docker-keycloak/templates/import/realm.json.j2 @@ -885,12 +885,14 @@ "email" ], "optionalClientScopes": [ - "nextcloud", "address", "phone", "organization", "offline_access", - "microprofile-jwt" + "microprofile-jwt", + "{{ applications[application_id]scopes.rbac_roles }}", + "{{ applications[application_id]scopes.nextcloud }}" + ] } ], @@ -1195,7 +1197,7 @@ }, { "id": "15dd4961-5b4f-4635-a3f1-a21e1fa7bf3a", - "name": "nextcloud", + "name": "{{ applications[application_id]scopes.nextcloud }}", "description": "Optimized mappers for nextcloud oidc_login with ldap.", "protocol": "openid-connect", "attributes": { @@ -1207,7 +1209,7 @@ "protocolMappers": [ { "id": "62190b21-f649-4aa2-806a-2bf7ba103ce1", - "name": "nextcloudQuota", + "name": "{{ ldap.user.attributes.nextcloud_quota }}", "protocol": "openid-connect", "protocolMapper": "oidc-usermodel-attribute-mapper", "consentRequired": false, @@ -1216,11 +1218,11 @@ "introspection.token.claim": "true", "multivalued": "false", "userinfo.token.claim": "true", - "user.attribute": "nextcloudQuota", + "user.attribute": "{{ ldap.user.attributes.nextcloud_quota }}", "id.token.claim": "true", "lightweight.claim": "false", "access.token.claim": "true", - "claim.name": "nextcloudQuota", + "claim.name": "{{ ldap.user.attributes.nextcloud_quota }}", "jsonType.label": "int" } }, @@ -1239,12 +1241,43 @@ "id.token.claim": "true", "lightweight.claim": "false", "access.token.claim": "true", - "claim.name": "{{ldap.attributes.user_id}}", + "claim.name": "{{ldap.user.attributes.id}}", "jsonType.label": "String" } } ] }, + { + "id": "59917c48-a7ef-464a-a8b0-ea24316db18e", + "name": "{{ applications[application_id]scopes.rbac_roles }}", + "description": "RBAC Groups", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "false", + "display.on.consent.screen": "true", + "gui.order": "", + "consent.screen.text": "" + }, + "protocolMappers": [ + { + "id": "0388cdf9-4751-484a-956c-431dbd872578", + "name": "groups", + "protocol": "openid-connect", + "protocolMapper": "oidc-group-membership-mapper", + "consentRequired": false, + "config": { + "full.path": "true", + "introspection.token.claim": "true", + "userinfo.token.claim": "true", + "multivalued": "true", + "id.token.claim": "true", + "lightweight.claim": "false", + "access.token.claim": "true", + "claim.name": "{{ oidc.claims.groups }}" + } + } + ] + }, { "id": "c07f07bc-c4f9-48c7-87e6-0a09fca6bfa0", "name": "web-origins", @@ -1637,12 +1670,13 @@ "basic" ], "defaultOptionalClientScopes": [ - "nextcloud", "offline_access", "address", "phone", "microprofile-jwt", - "organization" + "organization", + "{{ applications[application_id]scopes.rbac_roles }}", + "{{ applications[application_id]scopes.nextcloud }}" ], "browserSecurityHeaders": { "contentSecurityPolicyReportOnly": "", @@ -1792,7 +1826,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},{\"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\"}]}" + "{\"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.user.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\"}]}" ] } } @@ -1858,12 +1892,12 @@ }, { "id": "12b99578-e0bf-4eeb-b0fb-8e400c0cd73e", - "name": "nextcloudQuota", + "name": "{{ ldap.user.attributes.nextcloud_quota }}", "providerId": "user-attribute-ldap-mapper", "subComponents": {}, "config": { "ldap.attribute": [ - "nextcloudQuota" + "{{ ldap.user.attributes.nextcloud_quota }}" ], "is.mandatory.in.ldap": [ "false" @@ -1881,7 +1915,86 @@ "false" ], "user.model.attribute": [ - "nextcloudQuota" + "{{ ldap.user.attributes.nextcloud_quota }}" + ] + } + }, + { + "id": "24cd9c3b-e22d-4540-bddf-ae7faac0196c", + "name": "SSH Public Key", + "providerId": "user-attribute-ldap-mapper", + "subComponents": {}, + "config": { + "ldap.attribute": [ + "{{ ldap.user.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.user.attributes.ssh_public_key }}" + ] + } + }, + { + "id": "f56e4551-c5b5-4596-b567-bc8309a74e72", + "name": "ldap-roles", + "providerId": "group-ldap-mapper", + "subComponents": {}, + "config": { + "membership.attribute.type": [ + "DN" + ], + "group.name.ldap.attribute": [ + "{{ ldap.user.attributes.fullname }}" + ], + "membership.user.ldap.attribute": [ + "{{ ldap.user.attributes.id }}" + ], + "preserve.group.inheritance": [ + "false" + ], + "groups.dn": [ + "{{ ldap.dn.ou.roles }}" + ], + "mode": [ + "LDAP_ONLY" + ], + "user.roles.retrieve.strategy": [ + "LOAD_GROUPS_BY_MEMBER_ATTRIBUTE" + ], + "groups.ldap.filter": [ + "(objectClass=groupOfNames)" + ], + "membership.ldap.attribute": [ + "member" + ], + "ignore.missing.groups": [ + "true" + ], + "group.object.classes": [ + "groupOfNames" + ], + "memberof.ldap.attribute": [ + "memberOf" + ], + "drop.non.existing.groups.during.sync": [ + "false" + ], + "groups.path": [ + "{{ applications[application_id].rbac_groups }}" ] } }, @@ -1944,7 +2057,7 @@ "true" ], "ldap.full.name.attribute": [ - "{{ ldap.attributes.fullname }}" + "{{ ldap.user.attributes.fullname }}" ] } }, @@ -1955,7 +2068,7 @@ "subComponents": {}, "config": { "ldap.attribute": [ - "{{ldap.attributes.user_id}}" + "{{ldap.user.attributes.id}}" ], "is.mandatory.in.ldap": [ "true" @@ -1984,7 +2097,7 @@ "subComponents": {}, "config": { "ldap.attribute": [ - "{{ ldap.attributes.ssh_public_key }}" + "{{ ldap.user.attributes.ssh_public_key }}" ], "is.mandatory.in.ldap": [ "false" @@ -2002,7 +2115,7 @@ "true" ], "user.model.attribute": [ - "{{ ldap.attributes.ssh_public_key }}" + "{{ ldap.user.attributes.ssh_public_key }}" ] } }, @@ -2069,7 +2182,7 @@ "-1" ], "usernameLDAPAttribute": [ - "{{ldap.attributes.user_id}}" + "{{ldap.user.attributes.id}}" ], "bindDn": [ "{{ldap.dn.administrator.data}}" @@ -2081,7 +2194,7 @@ "other" ], "uuidLDAPAttribute": [ - "{{ldap.attributes.user_id}}" + "{{ldap.user.attributes.id}}" ], "allowKerberosAuthentication": [ "false" @@ -2111,10 +2224,10 @@ "false" ], "userObjectClasses": [ - "{{ ldap.user_objects | join(', ') }}" + "{{ ldap.user.objects | join(', ') }}" ], "rdnLDAPAttribute": [ - "{{ldap.attributes.user_id}}" + "{{ldap.user.attributes.id}}" ], "editMode": [ "WRITABLE" diff --git a/roles/docker-keycloak/vars/configuration.yml b/roles/docker-keycloak/vars/configuration.yml index 9ae4f208..5df3b4ac 100644 --- a/roles/docker-keycloak/vars/configuration.yml +++ b/roles/docker-keycloak/vars/configuration.yml @@ -19,4 +19,9 @@ csp: unsafe-inline: true domains: canonical: - - "auth.{{ primary_domain }}" \ No newline at end of file + - "auth.{{ primary_domain }}" +scopes: + rbac_roles: rbac_roles + nextcloud: nextcloud + +rbac_groups: "/rbac" diff --git a/roles/docker-ldap/tasks/add_user_objects.yml b/roles/docker-ldap/tasks/add_user_objects.yml index a8831ed2..36cb5ff2 100644 --- a/roles/docker-ldap/tasks/add_user_objects.yml +++ b/roles/docker-ldap/tasks/add_user_objects.yml @@ -9,7 +9,7 @@ attrs: - dn - objectClass - - "{{ ldap.attributes.user_id }}" + - "{{ ldap.user.attributes.id }}" register: ldap_users_with_classes - name: Add only missing auxiliary classes @@ -28,7 +28,7 @@ label: "{{ item.dn }}" vars: missing_auxiliary: >- - {{ ldap.user_objects.auxiliary + {{ (ldap.user.objects.auxiliary.values() | list) | difference(item.objectClass | default([])) }} when: missing_auxiliary | length > 0 diff --git a/roles/docker-ldap/tasks/main.yml b/roles/docker-ldap/tasks/main.yml index 8b0db7dc..22225286 100644 --- a/roles/docker-ldap/tasks/main.yml +++ b/roles/docker-ldap/tasks/main.yml @@ -63,11 +63,11 @@ ############################################################################### - name: Ensure LDAP users exist community.general.ldap_entry: - dn: "{{ ldap.attributes.user_id }}={{ item.key }},{{ ldap.dn.ou.users }}" + dn: "{{ ldap.user.attributes.id }}={{ item.key }},{{ ldap.dn.ou.users }}" server_uri: "{{ ldap_server_uri }}" bind_dn: "{{ ldap.dn.administrator.data }}" bind_pw: "{{ ldap.bind_credential }}" - objectClass: "{{ ldap.user_objects.structural }}" + objectClass: "{{ ldap.user.objects.structural }}" attributes: uid: "{{ item.value.username }}" sn: "{{ item.value.sn | default(item.key) }}" @@ -89,12 +89,12 @@ ############################################################################### - name: Ensure required objectClass values and mail address are present community.general.ldap_attrs: - dn: "{{ ldap.attributes.user_id }}={{ item.key }},{{ ldap.dn.ou.users }}" + dn: "{{ ldap.user.attributes.id }}={{ item.key }},{{ ldap.dn.ou.users }}" server_uri: "{{ ldap_server_uri }}" bind_dn: "{{ ldap.dn.administrator.data }}" bind_pw: "{{ ldap.bind_credential }}" attributes: - objectClass: "{{ ldap.user_objects.structural }}" + objectClass: "{{ ldap.user.objects.structural }}" mail: "{{ item.value.email }}" state: exact async: 60 diff --git a/roles/docker-ldap/tasks/schemas/nextcloud.yml b/roles/docker-ldap/tasks/schemas/nextcloud.yml index 00ff7cb4..c5721d15 100644 --- a/roles/docker-ldap/tasks/schemas/nextcloud.yml +++ b/roles/docker-ldap/tasks/schemas/nextcloud.yml @@ -8,9 +8,9 @@ vars: schema_name: "nextcloud" attribute_defs: - - "( 1.3.6.1.4.1.99999.1 NAME 'nextcloudQuota' DESC 'Quota for Nextcloud' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )" + - "( 1.3.6.1.4.1.99999.1 NAME '{{ ldap.user.attributes.nextcloud_quota }}' DESC 'Quota for Nextcloud' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )" objectclass_defs: - - "( 1.3.6.1.4.1.99999.2 NAME 'nextcloudUser' DESC 'Auxiliary class for Nextcloud attributes' AUXILIARY MAY ( nextcloudQuota ) )" + - "( 1.3.6.1.4.1.99999.2 NAME 'nextcloudUser' DESC 'Auxiliary class for Nextcloud attributes' AUXILIARY MAY ( {{ ldap.user.attributes.nextcloud_quota }} ) )" command: > ldapsm -s {{ ldap_server_uri }} diff --git a/roles/docker-ldap/tasks/schemas/openssh_lpk.yml b/roles/docker-ldap/tasks/schemas/openssh_lpk.yml index 92cc16b1..12efab44 100644 --- a/roles/docker-ldap/tasks/schemas/openssh_lpk.yml +++ b/roles/docker-ldap/tasks/schemas/openssh_lpk.yml @@ -8,16 +8,16 @@ vars: schema_name: "openssh-lpk" attribute_defs: - - "( 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.1 NAME '{{ ldap.user.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: - >- ( 1.3.6.1.4.1.24552.2.1 - NAME 'ldapPublicKey' + NAME '{{ ldap.user.objects.auxiliary.ssh_public_key }}' DESC 'Auxiliary class for OpenSSH public keys' SUP top AUXILIARY - MAY ( {{ ldap.attributes.ssh_public_key }} $ sshFingerprint ) ) + MAY ( {{ ldap.user.attributes.ssh_public_key }} $ sshFingerprint ) ) command: > ldapsm diff --git a/roles/docker-nextcloud/templates/config/oidc.config.php.j2 b/roles/docker-nextcloud/templates/config/oidc.config.php.j2 index b00cd569..ba6b7aa8 100644 --- a/roles/docker-nextcloud/templates/config/oidc.config.php.j2 +++ b/roles/docker-nextcloud/templates/config/oidc.config.php.j2 @@ -97,10 +97,10 @@ return array ( // note: on Keycloak, OIDC name claim = "${given_name} ${family_name}" or one of them if any is missing // 'oidc_login_attributes' => array ( - 'id' => '{{ldap.attributes.user_id}}', + 'id' => '{{ldap.user.attributes.id}}', 'name' => 'name', 'mail' => 'email', - 'quota' => 'nextcloudQuota', + 'quota' => '{{ ldap.user.attributes.nextcloud_quota }}', # 'home' => 'homeDirectory', # Not implemented yet 'ldap_uid' => '{{oidc.attributes.username}}', # 'groups' => 'ownCloudGroups', # Not implemented yet diff --git a/roles/docker-nextcloud/vars/plugins/user_ldap.yml b/roles/docker-nextcloud/vars/plugins/user_ldap.yml index a2e193eb..c3bdf8a8 100644 --- a/roles/docker-nextcloud/vars/plugins/user_ldap.yml +++ b/roles/docker-nextcloud/vars/plugins/user_ldap.yml @@ -181,4 +181,4 @@ plugin_configuration: - appid: "user_ldap" configkey: "s01ldap_expert_username_attr" - configvalue: "{{ldap.attributes.user_id}}" \ No newline at end of file + configvalue: "{{ldap.user.attributes.id}}" \ No newline at end of file diff --git a/roles/docker-oauth2-proxy/templates/oauth2-proxy-keycloak.cfg.j2 b/roles/docker-oauth2-proxy/templates/oauth2-proxy-keycloak.cfg.j2 index de2b44f7..c19eeaf0 100644 --- a/roles/docker-oauth2-proxy/templates/oauth2-proxy-keycloak.cfg.j2 +++ b/roles/docker-oauth2-proxy/templates/oauth2-proxy-keycloak.cfg.j2 @@ -11,13 +11,14 @@ client_id = "{{ oidc.client.id }}" redirect_url = "{{ web_protocol }}://{{ domains | get_domain(oauth2_proxy_application_id) }}/oauth2/callback" oidc_issuer_url = "{{ oidc.client.issuer_url }}" provider = "oidc" -provider_display_name = "Keycloak" +provider_display_name = "{{ oidc.button_text }}" {% if applications[oauth2_proxy_application_id].oauth2_proxy.allowed_groups is defined %} {# role based restrictions #} -scope = "openid email profile groups" -oidc_groups_claim = "realm_access.roles" +scope = "openid email profile {{ oidc.claims.groups }}" +oidc_groups_claim = "{{ oidc.claims.groups }}" allowed_groups = {{ applications[oauth2_proxy_application_id].oauth2_proxy.allowed_groups | tojson }} +email_domains = ["*"] {% else %} email_domains = "{{ primary_domain }}" {% endif %} \ No newline at end of file diff --git a/roles/docker-openproject/vars/ldap.yml b/roles/docker-openproject/vars/ldap.yml index f8fcf7e2..aaf75a8b 100644 --- a/roles/docker-openproject/vars/ldap.yml +++ b/roles/docker-openproject/vars/ldap.yml @@ -5,10 +5,10 @@ openproject_ldap: account: "{{ ldap.dn.administrator.data }}" # Bind DN (used for authentication) account_password: "{{ ldap.bind_credential }}" # Bind password base_dn: "{{ ldap.dn.ou.users }}" # Base DN for user search - attr_login: "{{ ldap.attributes.user_id }}" # LDAP attribute used for login + attr_login: "{{ ldap.user.attributes.id }}" # LDAP attribute used for login attr_firstname: "givenName" # LDAP attribute for first name - attr_lastname: "{{ ldap.attributes.surname }}" # LDAP attribute for last name - attr_mail: "{{ ldap.attributes.mail }}" # LDAP attribute for email + attr_lastname: "{{ ldap.user.attributes.surname }}" # LDAP attribute for last name + attr_mail: "{{ ldap.user.attributes.mail }}" # LDAP attribute for email attr_admin: "{{ openproject_filters.administrators }}" # Optional: LDAP attribute for admin group (leave empty if unused) onthefly_register: true # Automatically create users on first login tls_mode: 0 # 0 = No TLS, 1 = TLS, 2 = STARTTLS diff --git a/roles/docker-snipe-it/tasks/ldap.yml b/roles/docker-snipe-it/tasks/ldap.yml index 618404ed..9973f14e 100644 --- a/roles/docker-snipe-it/tasks/ldap.yml +++ b/roles/docker-snipe-it/tasks/ldap.yml @@ -47,16 +47,16 @@ $s->ldap_uname = "{{ ldap.dn.administrator.data }}"; $s->ldap_basedn = "{{ ldap.dn.ou.users }}"; $s->ldap_filter = "&(objectClass=inetOrgPerson)"; - $s->ldap_username_field = "{{ ldap.attributes.user_id }}"; - $s->ldap_fname_field = "{{ ldap.attributes.firstname }}"; - $s->ldap_lname_field = "{{ ldap.attributes.surname }}"; + $s->ldap_username_field = "{{ ldap.user.attributes.id }}"; + $s->ldap_fname_field = "{{ ldap.user.attributes.firstname }}"; + $s->ldap_lname_field = "{{ ldap.user.attributes.surname }}"; $s->ldap_auth_filter_query = "uid="; $s->ldap_version = 3; $s->ldap_pw_sync = 0; $s->is_ad = 0; $s->ad_domain = ""; $s->ldap_default_group = ""; - $s->ldap_email = "{{ ldap.attributes.mail }}"; + $s->ldap_email = "{{ ldap.user.attributes.mail }}"; $s->custom_forgot_pass_url = "{{ oidc.client.reset_credentials }}"; $s->save(); EOF'