From 4f7de83dd096d05d558f96de973e0cba7f067aaa Mon Sep 17 00:00:00 2001 From: mjeremym2 <93650360+mjeremym2@users.noreply.github.com> Date: Fri, 7 Jun 2024 11:08:24 +0100 Subject: [PATCH] Uses a filter to identify ADMIN users. Both "admin" and "admin-filter" can be used together or uniquely. --- docs/docs/en/architecture/configuration.md | 78 +++++++++---------- .../api/security/impl/ldap/LdapService.java | 42 +++++----- .../security/impl/ldap/LdapServiceTest.java | 3 +- .../src/test/resources/application.yaml | 5 +- 4 files changed, 64 insertions(+), 64 deletions(-) diff --git a/docs/docs/en/architecture/configuration.md b/docs/docs/en/architecture/configuration.md index ab834047c6..ed59e4eb84 100644 --- a/docs/docs/en/architecture/configuration.md +++ b/docs/docs/en/architecture/configuration.md @@ -242,45 +242,45 @@ The default configuration is as follows: Location: `api-server/conf/application.yaml` -| Parameters | Default value | Description | -|-------------------------------------------------------|---------------------------------------|------------------------------------------------------------------------------------------------| -| server.port | 12345 | api service communication port | -| server.servlet.session.timeout | 120m | session timeout | -| server.servlet.context-path | /dolphinscheduler/ | request path | -| spring.servlet.multipart.max-file-size | 1024MB | maximum file size | -| spring.servlet.multipart.max-request-size | 1024MB | maximum request size | -| server.jetty.max-http-post-size | 5000000 | jetty maximum post size | -| spring.banner.charset | UTF-8 | message encoding | -| spring.jackson.time-zone | UTC | time zone | -| spring.jackson.date-format | "yyyy-MM-dd HH:mm:ss" | time format | -| spring.messages.basename | i18n/messages | i18n config | -| security.authentication.type | PASSWORD | authentication type | -| security.authentication.ldap.user.admin | read-only-admin | admin user account when you log-in with LDAP using the uid attribute of the user | -| security.authentication.ldap.user.admin-attribute | memberOf | Attribute to identify a user account(s) when you log-in with LDAP (alt to a single account) | -| security.authentication.ldap.user.admin-value | cn=admin,ou=dolphin,dc=example,dc=com | Value for the admin-attirubte that identifies the user account as admin with LDAP | -| security.authentication.ldap.urls | ldap://ldap.forumsys.com:389/ | LDAP urls | -| security.authentication.ldap.base.dn | dc=example,dc=com | LDAP base dn | -| security.authentication.ldap.username | cn=read-only-admin,dc=example,dc=com | LDAP username | -| security.authentication.ldap.password | password | LDAP password | -| security.authentication.ldap.user.identity-attribute | uid | LDAP user identity attribute | -| security.authentication.ldap.user.email-attribute | mail | LDAP user email attribute | -| security.authentication.ldap.user.not-exist-action | CREATE | action when ldap user is not exist,default value: CREATE. Optional values include(CREATE,DENY) | -| security.authentication.ldap.ssl.enable | false | LDAP ssl switch | -| security.authentication.ldap.ssl.trust-store | ldapkeystore.jks | LDAP jks file absolute path | -| security.authentication.ldap.ssl.trust-store-password | password | LDAP jks password | -| security.authentication.casdoor.user.admin | | admin user account when you log-in with Casdoor | -| casdoor.endpoint | | Casdoor server url | -| casdoor.client-id | | id in Casdoor | -| casdoor.client-secret | | secret in Casdoor | -| casdoor.certificate | | certificate in Casdoor | -| casdoor.organization-name | | organization name in Casdoor | -| casdoor.application-name | | application name in Casdoor | -| casdoor.redirect-url | | doplhinscheduler login url | -| api.traffic.control.global.switch | false | traffic control global switch | -| api.traffic.control.max-global-qps-rate | 300 | global max request number per second | -| api.traffic.control.tenant-switch | false | traffic control tenant switch | -| api.traffic.control.default-tenant-qps-rate | 10 | default tenant max request number per second | -| api.traffic.control.customize-tenant-qps-rate | | customize tenant max request number per second | +| Parameters | Default value | Description | +|-------------------------------------------------------|-------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------| +| server.port | 12345 | api service communication port | +| server.servlet.session.timeout | 120m | session timeout | +| server.servlet.context-path | /dolphinscheduler/ | request path | +| spring.servlet.multipart.max-file-size | 1024MB | maximum file size | +| spring.servlet.multipart.max-request-size | 1024MB | maximum request size | +| server.jetty.max-http-post-size | 5000000 | jetty maximum post size | +| spring.banner.charset | UTF-8 | message encoding | +| spring.jackson.time-zone | UTC | time zone | +| spring.jackson.date-format | "yyyy-MM-dd HH:mm:ss" | time format | +| spring.messages.basename | i18n/messages | i18n config | +| security.authentication.type | PASSWORD | authentication type | +| security.authentication.ldap.user.admin | read-only-admin | admin user account when you log-in with LDAP using the uid attribute of the user | +| security.authentication.ldap.user.admin-filter | (&(ou=scientists)(uniqueMember=uid={0},dc=example,dc=com)) | Alternative to "admin" were admin accounts identified by role with LDAP using the uid attribute of the user | +| | (&(sAMAccountName={0})(memberOf=CN=admin,OU=dolphin,DC=example,DC=com)) | Alternative example were role attributes with in the LDAP account (memberOf LDAP setup) | +| security.authentication.ldap.urls | ldap://ldap.forumsys.com:389/ | LDAP urls | +| security.authentication.ldap.base.dn | dc=example,dc=com | LDAP base dn | +| security.authentication.ldap.username | cn=read-only-admin,dc=example,dc=com | LDAP username | +| security.authentication.ldap.password | password | LDAP password | +| security.authentication.ldap.user.identity-attribute | uid | LDAP user identity attribute | +| security.authentication.ldap.user.email-attribute | mail | LDAP user email attribute | +| security.authentication.ldap.user.not-exist-action | CREATE | action when ldap user is not exist,default value: CREATE. Optional values include(CREATE,DENY) | +| security.authentication.ldap.ssl.enable | false | LDAP ssl switch | +| security.authentication.ldap.ssl.trust-store | ldapkeystore.jks | LDAP jks file absolute path | +| security.authentication.ldap.ssl.trust-store-password | password | LDAP jks password | +| security.authentication.casdoor.user.admin | | admin user account when you log-in with Casdoor | +| casdoor.endpoint | | Casdoor server url | +| casdoor.client-id | | id in Casdoor | +| casdoor.client-secret | | secret in Casdoor | +| casdoor.certificate | | certificate in Casdoor | +| casdoor.organization-name | | organization name in Casdoor | +| casdoor.application-name | | application name in Casdoor | +| casdoor.redirect-url | | doplhinscheduler login url | +| api.traffic.control.global.switch | false | traffic control global switch | +| api.traffic.control.max-global-qps-rate | 300 | global max request number per second | +| api.traffic.control.tenant-switch | false | traffic control tenant switch | +| api.traffic.control.default-tenant-qps-rate | 10 | default tenant max request number per second | +| api.traffic.control.customize-tenant-qps-rate | | customize tenant max request number per second | ### Master Server related configuration diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/ldap/LdapService.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/ldap/LdapService.java index bc1cf2e491..a64ed6b55d 100644 --- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/ldap/LdapService.java +++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/ldap/LdapService.java @@ -79,11 +79,8 @@ public class LdapService { @Value("${security.authentication.ldap.user.email-attribute:#{null}}") private String ldapEmailAttribute; - @Value("${security.authentication.ldap.user.admin-attribute:#{null}}") - private String ldapAdminIdentifingAttribute; - - @Value("${security.authentication.ldap.user.admin-value:#{null}}") - private String ldapAdminIdentifingValue; + @Value("${security.authentication.ldap.user.admin-filter:#{null}}") + private String ldapAdminUserFilter; @Value("${security.authentication.ldap.user.not-exist-action:CREATE}") private String ldapUserNotExistAction; @@ -121,7 +118,7 @@ public class LdapService { * @return user email */ public Map ldapLogin(String userId, String userPwd) { - Map ldapAttributeMap = null; + Map ldapAttributeMap = new HashMap<>(); Properties searchEnv = getManagerLdapEnv(); LdapContext ctx = null; @@ -129,7 +126,7 @@ public class LdapService { // Connect to the LDAP server and Authenticate with a service user of whom we know the DN and credentials ctx = new InitialLdapContext(searchEnv, null); SearchControls sc = new SearchControls(); - sc.setReturningAttributes(new String[]{ldapEmailAttribute, ldapAdminIdentifingAttribute}); + sc.setReturningAttributes(new String[]{ldapEmailAttribute}); sc.setSearchScope(SearchControls.SUBTREE_SCOPE); NamingEnumeration results = null; @@ -141,6 +138,7 @@ public class LdapService { results = ctx.search(ldapBaseDn, filter.toString(), sc); } + // Get all requested attributes if (results.hasMore()) { // get the users DN (distinguishedName) from the result SearchResult result = results.next(); @@ -157,29 +155,29 @@ public class LdapService { return null; } - if (ldapAttributeMap == null) { - ldapAttributeMap = new HashMap<>(); - UserType userType = - userId.equalsIgnoreCase(adminUserId) ? UserType.ADMIN_USER : UserType.GENERAL_USER; - - ldapAttributeMap.put(ATTRIBUTE_USER_TYPE, userType.toString()); - } - Attribute attr = attrs.next(); if (attr.getID().equals(ldapEmailAttribute)) { String value = (String) attr.get(); ldapAttributeMap.put(ATTRIBUTE_EMAIL, value); - } else if (ldapAdminIdentifingAttribute != null - && attr.getID().equals(ldapAdminIdentifingAttribute)) { - String value = (String) attr.get(); - - if (value != null && value.equals(ldapAdminIdentifingValue)) { - ldapAttributeMap.put(ATTRIBUTE_USER_TYPE, UserType.ADMIN_USER.toString()); - } } } } + + // Check for admin role + UserType userType = + userId.equalsIgnoreCase(adminUserId) ? UserType.ADMIN_USER : UserType.GENERAL_USER; + + ldapAttributeMap.put(ATTRIBUTE_USER_TYPE, userType.toString()); + + if (ldapAdminUserFilter != null) { + results = ctx.search(ldapBaseDn, ldapAdminUserFilter, new Object[]{userId}, sc); + + if (results.hasMore()) { + // found the users with or part of the admin context + ldapAttributeMap.put(ATTRIBUTE_USER_TYPE, UserType.ADMIN_USER.toString()); + } + } } catch (NamingException e) { log.error("ldap search error", e); return null; diff --git a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/security/impl/ldap/LdapServiceTest.java b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/security/impl/ldap/LdapServiceTest.java index 76a8ff1312..393ef82e42 100644 --- a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/security/impl/ldap/LdapServiceTest.java +++ b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/security/impl/ldap/LdapServiceTest.java @@ -50,8 +50,7 @@ import org.springframework.test.context.TestPropertySource; "security.authentication.ldap.ssl.enable=false", "security.authentication.ldap.ssl.trust-store=", "security.authentication.ldap.ssl.trust-store-password=", - "security.authentication.ldap.user.admin-attribute=uid", - "security.authentication.ldap.user.admin-value=tesla" + "security.authentication.ldap.user.admin-filter=(&(ou=scientists)(uniqueMember=uid={0},dc=example,dc=com))" }) public class LdapServiceTest { diff --git a/dolphinscheduler-api/src/test/resources/application.yaml b/dolphinscheduler-api/src/test/resources/application.yaml index 5eb7e1f8d7..2debf1c45c 100644 --- a/dolphinscheduler-api/src/test/resources/application.yaml +++ b/dolphinscheduler-api/src/test/resources/application.yaml @@ -105,8 +105,11 @@ security: username: cn=read-only-admin,dc=example,dc=com password: password user: - # admin userId when you use LDAP login + # admin userId when you use LDAP login. Properties admin are admin-filter are not mutually exclusive + # were ONE uses can be identified by userId and the rest using a role based filter admin: read-only-admin + # alternative to admin using a ROLE when you use LDAP login, all scientists are admin users + admin-filer: (&(ou=scientists)(uniqueMember=uid={0},dc=example,dc=com)) identity-attribute: uid email-attribute: mail # action when ldap user is not exist (supported types: CREATE,DENY)