This is an automated email from the ASF dual-hosted git repository.
caishunfeng pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/dolphinscheduler.git
The following commit(s) were added to refs/heads/dev by this push:
new 627c76b75a [Improvement-16106] Add admin-user-filter in LDAP (#16826)
627c76b75a is described below
commit 627c76b75a11afdae0b8b6656385a280aec4fdba
Author: xiangzihao <[email protected]>
AuthorDate: Fri Nov 22 17:39:18 2024 +0800
[Improvement-16106] Add admin-user-filter in LDAP (#16826)
* improvement 16106
* fix ut
* fix comment
* fix spotless
---
.github/workflows/api-test.yml | 2 +
docs/docs/en/guide/security/authentication-type.md | 37 ++----
docs/docs/zh/guide/security/authentication-type.md | 50 +++-----
dolphinscheduler-api-test/README.md | 26 +++++
.../api/test/cases/ExecutorAPITest.java | 2 +
.../api/test/cases/LdapLoginAPITest.java | 112 ++++++++++++++++++
.../api/test/entity/GetUserInfoResponseData.java | 35 ++++--
.../api/test/pages/security/UserPage.java | 22 ++--
.../resources/docker/ldap-login}/application.yaml | 19 +--
.../docker/ldap-login/docker-compose.yaml | 63 ++++++++++
dolphinscheduler-api-test/pom.xml | 5 +-
.../LdapLoginResult.java} | 22 ++--
.../api/security/impl/AbstractAuthenticator.java | 8 +-
.../api/security/impl/ldap/LdapAuthenticator.java | 11 +-
.../api/security/impl/ldap/LdapService.java | 129 ++++++++++++++-------
.../security/impl/pwd/PasswordAuthenticator.java | 4 +-
.../security/impl/sso/CasdoorAuthenticator.java | 6 +-
.../src/main/resources/application.yaml | 12 +-
.../api/security/SecurityConfigLDAPTest.java | 1 +
.../security/impl/ldap/LdapAuthenticatorTest.java | 20 ++--
.../api/security/impl/ldap/LdapServiceTest.java | 107 -----------------
.../src/test/resources/application.yaml | 9 +-
.../src/main/resources/application.yaml | 12 +-
23 files changed, 427 insertions(+), 287 deletions(-)
diff --git a/.github/workflows/api-test.yml b/.github/workflows/api-test.yml
index fffebe801a..b31d431c28 100644
--- a/.github/workflows/api-test.yml
+++ b/.github/workflows/api-test.yml
@@ -115,6 +115,8 @@ jobs:
class: org.apache.dolphinscheduler.api.test.cases.ExecutorAPITest
- name: WorkflowInstanceAPITest
class:
org.apache.dolphinscheduler.api.test.cases.WorkflowInstanceAPITest
+ - name: LdapLoginAPITest
+ class: org.apache.dolphinscheduler.api.test.cases.LdapLoginAPITest
env:
RECORDING_PATH: /tmp/recording-${{ matrix.case.name }}
steps:
diff --git a/docs/docs/en/guide/security/authentication-type.md
b/docs/docs/en/guide/security/authentication-type.md
index 31c8d05de3..ae82f54976 100644
--- a/docs/docs/en/guide/security/authentication-type.md
+++ b/docs/docs/en/guide/security/authentication-type.md
@@ -10,21 +10,23 @@
security:
authentication:
# Authentication types (supported types: PASSWORD,LDAP,CASDOOR_SSO)
- type: PASSWORD
+ type: LDAP
# IF you set type `LDAP`, below config will be effective
ldap:
# ldap server config
- urls: ldap://ldap.forumsys.com:389/
+ url: ldap://ldap.forumsys.com:389/
base-dn: dc=example,dc=com
- username: cn=read-only-admin,dc=example,dc=com
+ username: cn=admin,dc=example,dc=com
password: password
user:
# admin userId when you use LDAP login
- admin: read-only-admin
+ admin: ldap-admin
+ # user search filter to find admin user
+ admin-user-filter: (&(cn={0}))
identity-attribute: uid
email-attribute: mail
# action when ldap user is not exist (supported types: CREATE,DENY)
- not-exist-action: CREATE
+ not-exist-action: DENY
ssl:
enable: false
# jks file absolute path && password
@@ -71,31 +73,6 @@ casdoor:
redirect-url: ""
```
-For detailed explanation of specific fields, please see: [Api-server related
configuration](../../architecture/configuration.md)
-
-## LDAP Test
-
-We offer you a unit-test class while you can test the integration of
DolphinScheduler with LDAP without running the service.
-
->
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/security/impl/ldap/LdapServiceTest.java
-
-You can follow guide below:
-- Change`TestPropertySource`configuration to your LDAP information.
-- Change userId && userPwd to your information in the `ldapLogin` method.
-- Change the expected email to the return value you expect in the `ldapLogin`
method.
-- Run`ldapLogin`method and determine whether the LDAP login result is expected.
-
-If you want to enable ssl, please change configuration in `TestPropertySource`
like below:
-
-```
-security.authentication.ldap.ssl.enable=false
-// absolute path
-security.authentication.ldap.ssl.trust-store=/ldapkeystore.jks
-security.authentication.ldap.ssl.trust-store-password=yourpassword
-```
-
-Then run`ldapLoginSSL`method and determine whether the LDAP login result is
expected.
-
## Casdoor SSO
[Casdoor](https://casdoor.org/) is a UI-first Identity Access Management (IAM)
/ Single-Sign-On (SSO) platform based on OAuth 2.0, OIDC, SAML and CAS. You can
add SSO capability to Dolphinscheduler through Casdoor by following these steps:
diff --git a/docs/docs/zh/guide/security/authentication-type.md
b/docs/docs/zh/guide/security/authentication-type.md
index b32e13b46b..3a7b5a4772 100644
--- a/docs/docs/zh/guide/security/authentication-type.md
+++ b/docs/docs/zh/guide/security/authentication-type.md
@@ -14,22 +14,23 @@ security:
# IF you set type `LDAP`, below config will be effective
ldap:
# ldap server config
- urls: ldap://ldap.forumsys.com:389/
+ url: ldap://ldap.forumsys.com:389/
base-dn: dc=example,dc=com
- username: cn=read-only-admin,dc=example,dc=com
+ username: cn=admin,dc=example,dc=com
password: password
user:
- # admin userId when you use LDAP login
- admin: read-only-admin
- identity-attribute: uid
- email-attribute: mail
- # action when ldap user is not exist (supported types: CREATE,DENY)
- not-exist-action: CREATE
+ # admin userId when you use LDAP login
+ admin: ldap-admin
+ # user search filter to find admin user
+ identity-attribute: uid
+ email-attribute: mail
+ # action when ldap user is not exist (supported types: CREATE,DENY)
+ not-exist-action: DENY
ssl:
- enable: false
- # jks file absolute path && password
- trust-store: "/ldapkeystore.jks"
- trust-store-password: "password"
+ enable: false
+ # jks file absolute path && password
+ trust-store: "/ldapkeystore.jks"
+ trust-store-password: "password"
casdoor:
user:
admin: ""
@@ -71,31 +72,6 @@ casdoor:
redirect-url: ""
```
-具体字段解释详见:[Api-server相关配置](../../architecture/configuration.md)
-
-## 开发者LDAP测试
-
-我们提供了一个单元测试类,可以在不启动项目的情况下测试DolphinScheduler与LDAP的集成。
-
->
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/security/impl/ldap/LdapServiceTest.java
-
-使用步骤如下:
-- 修改`TestPropertySource`配置参数为你的LDAP信息;
-- 修改`ldapLogin`方法中的userId和userPwd为你的账号密码;
-- 修改`ldapLogin`方法中的expected email为正常登陆的返回值;
-- 执行`ldapLogin`方法,判断LDAP登陆结果是否为预期;
-
-如果你要启用ssl,请修改`TestPropertySource`配置中ssl相关参数为:
-
-```
-security.authentication.ldap.ssl.enable=false
-// absolute path
-security.authentication.ldap.ssl.trust-store=/ldapkeystore.jks
-security.authentication.ldap.ssl.trust-store-password=yourpassword
-```
-
-运行`ldapLoginSSL`方法,判断email是否为预期的返回值。
-
## 通过 Casdoor 实现 SSO 登录
Casdoor 是基于 OAuth 2.0、OIDC、SAML 和 CAS 的面向 UI
的身份访问管理(IAM)/单点登录(SSO)平台。您可以通过以下步骤通过 Casdoor 为 Dolphinscheduler 添加 SSO 功能:
diff --git a/dolphinscheduler-api-test/README.md
b/dolphinscheduler-api-test/README.md
index 9e48bc6430..1db1196841 100644
--- a/dolphinscheduler-api-test/README.md
+++ b/dolphinscheduler-api-test/README.md
@@ -43,3 +43,29 @@ class TenantAPITest {
}
```
+## Notes
+
+## Local development
+
+### Mac M1
+Add VM options to the test configuration in IntelliJ IDEA:
+```
+# In this mode you need to install docker desktop for mac and run it with
locally
+-Dm1_chip=true
+```
+
+### Running locally(without Docker)
+```
+# In this mode you need to start frontend and backend services locally
+-Dlocal=true
+```
+
+### Running locally(with Docker)
+```
+# In this mode you only need to install docker locally
+```
+
+- To run the tests locally, you need to have the DolphinScheduler running
locally. You should add `dolphinscheduler-api-test/pom.xml` to the maven project
+ Since it does not participate in project compilation, it is not in the main
project.
+- Running run test class
`org.apache.dolphinscheduler.api.test.cases.TenantAPITest` in the IDE.
+
diff --git
a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/ExecutorAPITest.java
b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/ExecutorAPITest.java
index b9430546b0..bf1d05691a 100644
---
a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/ExecutorAPITest.java
+++
b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/ExecutorAPITest.java
@@ -47,10 +47,12 @@ import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
+import org.junitpioneer.jupiter.DisableIfTestFails;
//TODO: Some test cases rely on WorkflowInstance APIs. Should complete
remaining cases after WorkflowInstance related API tests done.
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
@Slf4j
+@DisableIfTestFails
public class ExecutorAPITest {
private static final String username = "admin";
diff --git
a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/LdapLoginAPITest.java
b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/LdapLoginAPITest.java
new file mode 100644
index 0000000000..f2b9e4cadc
--- /dev/null
+++
b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/LdapLoginAPITest.java
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.api.test.cases;
+
+import org.apache.dolphinscheduler.api.test.core.DolphinScheduler;
+import org.apache.dolphinscheduler.api.test.entity.GetUserInfoResponseData;
+import org.apache.dolphinscheduler.api.test.entity.HttpResponse;
+import org.apache.dolphinscheduler.api.test.entity.LoginResponseData;
+import org.apache.dolphinscheduler.api.test.pages.LoginPage;
+import org.apache.dolphinscheduler.api.test.pages.security.UserPage;
+import org.apache.dolphinscheduler.api.test.utils.JSONUtils;
+import org.apache.dolphinscheduler.common.enums.UserType;
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Order;
+import org.junit.jupiter.api.Test;
+import org.junitpioneer.jupiter.DisableIfTestFails;
+
+@DolphinScheduler(composeFiles = "docker/ldap-login/docker-compose.yaml")
+@Slf4j
+@DisableIfTestFails
+public class LdapLoginAPITest {
+
+ private static String sessionId;
+
+ @Test
+ @Order(10)
+ public void testAdminUserLoginSuccess() {
+ final String username = "admin_user01";
+
+ final String password = "123";
+
+ LoginPage loginPage = new LoginPage();
+ HttpResponse loginHttpResponse = loginPage.login(username, password);
+ sessionId =
+ JSONUtils.convertValue(loginHttpResponse.getBody().getData(),
LoginResponseData.class).getSessionId();
+ UserPage userPage = new UserPage();
+ HttpResponse getUserInfoHttpResponse = userPage.getUserInfo(sessionId);
+ GetUserInfoResponseData getUserInfoResponseData =
+
JSONUtils.convertValue(getUserInfoHttpResponse.getBody().getData(),
GetUserInfoResponseData.class);
+ Assertions.assertEquals(username,
getUserInfoResponseData.getUserName());
+ Assertions.assertEquals(UserType.ADMIN_USER,
getUserInfoResponseData.getUserType());
+ }
+
+ @Test
+ @Order(20)
+ public void testAdminUserFilterLoginSuccess() {
+ final String username = "admin_user03";
+
+ final String password = "123";
+
+ LoginPage loginPage = new LoginPage();
+ HttpResponse loginHttpResponse = loginPage.login(username, password);
+ sessionId =
+ JSONUtils.convertValue(loginHttpResponse.getBody().getData(),
LoginResponseData.class).getSessionId();
+ UserPage userPage = new UserPage();
+ HttpResponse getUserInfoHttpResponse = userPage.getUserInfo(sessionId);
+ GetUserInfoResponseData getUserInfoResponseData =
+
JSONUtils.convertValue(getUserInfoHttpResponse.getBody().getData(),
GetUserInfoResponseData.class);
+ Assertions.assertEquals(username,
getUserInfoResponseData.getUserName());
+ Assertions.assertEquals(UserType.ADMIN_USER,
getUserInfoResponseData.getUserType());
+ }
+
+ @Test
+ @Order(30)
+ public void testGeneralUserLoginSuccess() {
+ final String username = "general_user02";
+
+ final String password = "123";
+
+ LoginPage loginPage = new LoginPage();
+ HttpResponse loginHttpResponse = loginPage.login(username, password);
+ sessionId =
+ JSONUtils.convertValue(loginHttpResponse.getBody().getData(),
LoginResponseData.class).getSessionId();
+ UserPage userPage = new UserPage();
+ HttpResponse getUserInfoHttpResponse = userPage.getUserInfo(sessionId);
+ GetUserInfoResponseData getUserInfoResponseData =
+
JSONUtils.convertValue(getUserInfoHttpResponse.getBody().getData(),
GetUserInfoResponseData.class);
+ Assertions.assertEquals(username,
getUserInfoResponseData.getUserName());
+ Assertions.assertEquals(UserType.GENERAL_USER,
getUserInfoResponseData.getUserType());
+ }
+
+ @Test
+ @Order(40)
+ public void testGeneralUserLoginFailed() {
+ final String username = "general_user02";
+
+ final String password = "1";
+
+ LoginPage loginPage = new LoginPage();
+ HttpResponse loginHttpResponse = loginPage.login(username, password);
+ Boolean loginResult = loginHttpResponse.getBody().getSuccess();
+ Assertions.assertFalse(loginResult);
+ }
+}
diff --git
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/pwd/PasswordAuthenticator.java
b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/entity/GetUserInfoResponseData.java
similarity index 52%
copy from
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/pwd/PasswordAuthenticator.java
copy to
dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/entity/GetUserInfoResponseData.java
index a7ae0dd9f1..7b5db1ab96 100644
---
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/pwd/PasswordAuthenticator.java
+++
b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/entity/GetUserInfoResponseData.java
@@ -15,15 +15,34 @@
* limitations under the License.
*/
-package org.apache.dolphinscheduler.api.security.impl.pwd;
+package org.apache.dolphinscheduler.api.test.entity;
-import org.apache.dolphinscheduler.api.security.impl.AbstractAuthenticator;
-import org.apache.dolphinscheduler.dao.entity.User;
+import org.apache.dolphinscheduler.common.enums.UserType;
-public class PasswordAuthenticator extends AbstractAuthenticator {
+import java.util.Date;
- @Override
- public User login(String userId, String password) {
- return userService.queryUser(userId, password);
- }
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class GetUserInfoResponseData {
+
+ private Integer id;
+ private String userName;
+ private String userPassword;
+ private String email;
+ private Integer phone;
+ private UserType userType;
+ private Integer tenantId;
+ private Integer state;
+ private String tenantCode;
+ private String queueName;
+ private String alertGroup;
+ private String queue;
+ private String timeZone;
+ private Date createTime;
+ private Date updateTime;
}
diff --git
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/pwd/PasswordAuthenticator.java
b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/security/UserPage.java
similarity index 56%
copy from
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/pwd/PasswordAuthenticator.java
copy to
dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/security/UserPage.java
index a7ae0dd9f1..f667bcfcd0 100644
---
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/pwd/PasswordAuthenticator.java
+++
b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/security/UserPage.java
@@ -15,15 +15,23 @@
* limitations under the License.
*/
-package org.apache.dolphinscheduler.api.security.impl.pwd;
+package org.apache.dolphinscheduler.api.test.pages.security;
-import org.apache.dolphinscheduler.api.security.impl.AbstractAuthenticator;
-import org.apache.dolphinscheduler.dao.entity.User;
+import org.apache.dolphinscheduler.api.test.core.Constants;
+import org.apache.dolphinscheduler.api.test.entity.HttpResponse;
+import org.apache.dolphinscheduler.api.test.utils.RequestClient;
-public class PasswordAuthenticator extends AbstractAuthenticator {
+import java.util.HashMap;
+import java.util.Map;
- @Override
- public User login(String userId, String password) {
- return userService.queryUser(userId, password);
+public class UserPage {
+
+ public HttpResponse getUserInfo(String sessionId) {
+ Map<String, String> headers = new HashMap<>();
+ headers.put(Constants.SESSION_ID_KEY, sessionId);
+
+ RequestClient requestClient = new RequestClient();
+
+ return requestClient.get("/users/get-user-info", headers, new
HashMap<>());
}
}
diff --git
a/dolphinscheduler-standalone-server/src/main/resources/application.yaml
b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/resources/docker/ldap-login/application.yaml
similarity index 97%
copy from dolphinscheduler-standalone-server/src/main/resources/application.yaml
copy to
dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/resources/docker/ldap-login/application.yaml
index 97b9b6d22d..51d8e23c2f 100644
--- a/dolphinscheduler-standalone-server/src/main/resources/application.yaml
+++
b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/resources/docker/ldap-login/application.yaml
@@ -86,19 +86,20 @@ registry:
security:
authentication:
# Authentication types (supported types: PASSWORD,LDAP,CASDOOR_SSO)
- type: PASSWORD
+ type: LDAP
# IF you set type `LDAP`, below config will be effective
ldap:
# ldap server config
- urls: ldap://ldap.forumsys.com:389/
- base-dn: dc=example,dc=com
- username: cn=read-only-admin,dc=example,dc=com
- password: password
+ url: ldap://openldap:1389/
+ base-dn: ou=users,dc=example,dc=org
+ username: cn=admin,dc=example,dc=org
+ password: adminpassword
user:
- # admin userId when you use LDAP login
- admin: read-only-admin
- identity-attribute: uid
- email-attribute: mail
+ # admin username when you use LDAP login
+ admin-username: admin_user01
+ admin-user-filter: (&(cn={0})(sn=Bar3))
+ identity-attribute: cn
+ email-attribute: uid
# action when ldap user is not exist (supported types: CREATE,DENY)
not-exist-action: CREATE
ssl:
diff --git
a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/resources/docker/ldap-login/docker-compose.yaml
b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/resources/docker/ldap-login/docker-compose.yaml
new file mode 100644
index 0000000000..28d91849c1
--- /dev/null
+++
b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/resources/docker/ldap-login/docker-compose.yaml
@@ -0,0 +1,63 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+version: "3.8"
+
+services:
+ dolphinscheduler:
+ image: apache/dolphinscheduler-standalone-server:ci
+ environment:
+ WORKER_TENANT_AUTO_CREATE: 'true'
+ ports:
+ - "12345:12345"
+ volumes:
+ -
./application.yaml:/opt/dolphinscheduler/standalone-server/conf/application.yaml
+ networks:
+ - api-test
+ healthcheck:
+ test: [ "CMD", "curl",
"http://localhost:12345/dolphinscheduler/actuator/health" ]
+ interval: 5s
+ timeout: 60s
+ retries: 120
+ depends_on:
+ - openldap
+ openldap:
+ hostname: openldap
+ image: bitnami/openldap:2.6
+ ports:
+ - '1389:1389'
+ - '1636:1636'
+ environment:
+ - LDAP_ADMIN_USERNAME=admin
+ - LDAP_ADMIN_PASSWORD=adminpassword
+ - LDAP_USERS=admin_user01,general_user02,admin_user03
+ - LDAP_PASSWORDS=123,123,123
+ - LDAP_ROOT=dc=example,dc=org
+ - LDAP_ADMIN_DN=cn=admin,dc=example,dc=org
+ networks:
+ - api-test
+ tty: true
+ stdin_open: true
+ restart: always
+ healthcheck:
+ test: ldapsearch -x -H 'ldap://127.0.0.1:1389' -D
'cn=admin,dc=example,dc=org' -w adminpassword -b 'ou=users,dc=example,dc=org'
'(cn=admin_user01)'
+ interval: 5s
+ timeout: 60s
+ retries: 120
+
+networks:
+ api-test:
diff --git a/dolphinscheduler-api-test/pom.xml
b/dolphinscheduler-api-test/pom.xml
index 095cefd64c..c16c6c6a6b 100644
--- a/dolphinscheduler-api-test/pom.xml
+++ b/dolphinscheduler-api-test/pom.xml
@@ -36,7 +36,8 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit.version>5.7.2</junit.version>
- <selenium.version>3.141.59</selenium.version>
+ <selenium.version>4.21.0</selenium.version>
+ <testcontainers.version>1.19.8</testcontainers.version>
<lombok.version>1.18.24</lombok.version>
<assertj-core.version>3.23.1</assertj-core.version>
<awaitility.version>4.1.0</awaitility.version>
@@ -133,7 +134,7 @@
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers-bom</artifactId>
- <version>1.18.1</version>
+ <version>${testcontainers.version}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
diff --git
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/pwd/PasswordAuthenticator.java
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/dto/LdapLoginResult.java
similarity index 67%
copy from
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/pwd/PasswordAuthenticator.java
copy to
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/dto/LdapLoginResult.java
index a7ae0dd9f1..47c458ac77 100644
---
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/pwd/PasswordAuthenticator.java
+++
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/dto/LdapLoginResult.java
@@ -15,15 +15,21 @@
* limitations under the License.
*/
-package org.apache.dolphinscheduler.api.security.impl.pwd;
+package org.apache.dolphinscheduler.api.dto;
-import org.apache.dolphinscheduler.api.security.impl.AbstractAuthenticator;
-import org.apache.dolphinscheduler.dao.entity.User;
+import org.apache.dolphinscheduler.common.enums.UserType;
-public class PasswordAuthenticator extends AbstractAuthenticator {
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
- @Override
- public User login(String userId, String password) {
- return userService.queryUser(userId, password);
- }
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class LdapLoginResult {
+
+ private boolean success;
+ private String ldapEmail;
+ private UserType userType;
+ private String userName;
}
diff --git
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/AbstractAuthenticator.java
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/AbstractAuthenticator.java
index 43b7e57402..7b9c3f5a43 100644
---
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/AbstractAuthenticator.java
+++
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/AbstractAuthenticator.java
@@ -59,16 +59,16 @@ public abstract class AbstractAuthenticator implements
Authenticator {
/**
* user login and return user in db
*
- * @param userId user identity field
+ * @param userName user identity field
* @param password user login password
* @return user object in databse
*/
- public abstract User login(@NonNull String userId, String password);
+ public abstract User login(@NonNull String userName, String password);
@Override
- public Result<Map<String, String>> authenticate(@NonNull String userId,
String password, @NonNull String ip) {
+ public Result<Map<String, String>> authenticate(@NonNull String userName,
String password, @NonNull String ip) {
Result<Map<String, String>> result = new Result<>();
- User user = login(userId, password);
+ User user = login(userName, password);
if (user == null) {
if (Objects.equals(securityConfig.getType(),
AuthenticationType.CASDOOR_SSO.name())) {
log.error("State or code entered incorrectly.");
diff --git
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/ldap/LdapAuthenticator.java
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/ldap/LdapAuthenticator.java
index 64f15eeeb2..030bc09fd7 100644
---
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/ldap/LdapAuthenticator.java
+++
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/ldap/LdapAuthenticator.java
@@ -17,6 +17,7 @@
package org.apache.dolphinscheduler.api.security.impl.ldap;
+import org.apache.dolphinscheduler.api.dto.LdapLoginResult;
import org.apache.dolphinscheduler.api.security.impl.AbstractAuthenticator;
import org.apache.dolphinscheduler.dao.entity.User;
@@ -30,14 +31,14 @@ public class LdapAuthenticator extends
AbstractAuthenticator {
LdapService ldapService;
@Override
- public User login(@NonNull String userId, String password) {
+ public User login(@NonNull String userName, String password) {
User user = null;
- String ldapEmail = ldapService.ldapLogin(userId, password);
- if (ldapEmail != null) {
+ LdapLoginResult ldapLoginResult = ldapService.ldapLogin(userName,
password);
+ if (ldapLoginResult.isSuccess()) {
// check if user exist
- user = userService.getUserByUserName(userId);
+ user = userService.getUserByUserName(userName);
if (user == null && ldapService.createIfUserNotExists()) {
- user = userService.createUser(ldapService.getUserType(userId),
userId, ldapEmail);
+ user = userService.createUser(ldapLoginResult.getUserType(),
userName, ldapLoginResult.getLdapEmail());
}
}
return user;
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 058280b81f..3a394809b4 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
@@ -17,11 +17,13 @@
package org.apache.dolphinscheduler.api.security.impl.ldap;
+import org.apache.dolphinscheduler.api.dto.LdapLoginResult;
import org.apache.dolphinscheduler.api.security.LdapUserNotExistActionType;
import org.apache.dolphinscheduler.common.enums.UserType;
import org.apache.commons.lang3.StringUtils;
+import java.util.Objects;
import java.util.Properties;
import javax.naming.Context;
@@ -46,11 +48,14 @@ import org.springframework.stereotype.Component;
@Slf4j
public class LdapService {
- @Value("${security.authentication.ldap.user.admin:#{null}}")
- private String adminUserId;
+ @Value("${security.authentication.ldap.user.admin-username:#{null}}")
+ private String ldapAdminUserName;
- @Value("${security.authentication.ldap.urls:#{null}}")
- private String ldapUrls;
+ @Value("${security.authentication.ldap.user.admin-user-filter:#{null}}")
+ private String ldapAdminUserFilter;
+
+ @Value("${security.authentication.ldap.url:#{null}}")
+ private String ldapUrl;
@Value("${security.authentication.ldap.base-dn:#{null}}")
private String ldapBaseDn;
@@ -67,7 +72,7 @@ public class LdapService {
@Value("${security.authentication.ldap.user.email-attribute:#{null}}")
private String ldapEmailAttribute;
- @Value("${security.authentication.ldap.user.not-exist-action:CREATE}")
+ @Value("${security.authentication.ldap.user.not-exist-action:DENY}")
private String ldapUserNotExistAction;
@Value("${security.authentication.ldap.ssl.enable:false}")
@@ -79,56 +84,58 @@ public class LdapService {
@Value("${security.authentication.ldap.ssl.trust-store-password:#{null}}")
private String trustStorePassword;
- /***
- * get user type by configured admin userId
- * @param userId login userId
- * @return user type
- */
- public UserType getUserType(String userId) {
- return adminUserId.equalsIgnoreCase(userId) ? UserType.ADMIN_USER :
UserType.GENERAL_USER;
- }
-
/**
- * login by userId and return user email
- *
- * @param userId user identity id
- * @param userPwd user login password
- * @return user email
+ * login by userName and return LdapLoginResult
*/
- public String ldapLogin(String userId, String userPwd) {
+ public LdapLoginResult ldapLogin(String userName, String userPwd) {
Properties searchEnv = getManagerLdapEnv();
LdapContext ctx = null;
+ LdapLoginResult ldapLoginResult = new LdapLoginResult();
+ ldapLoginResult.setSuccess(false);
+ if (StringUtils.isEmpty(ldapEmailAttribute)) {
+ log.warn("ldap email attribute is empty, skipping ldap
authentication");
+ return ldapLoginResult;
+ }
+
try {
// 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});
sc.setSearchScope(SearchControls.SUBTREE_SCOPE);
- EqualsFilter filter = new
EqualsFilter(ldapUserIdentifyingAttribute, userId);
- NamingEnumeration<SearchResult> results = ctx.search(ldapBaseDn,
filter.toString(), sc);
- if (results.hasMore()) {
- // get the users DN (distinguishedName) from the result
- SearchResult result = results.next();
- NamingEnumeration<? extends Attribute> attrs =
result.getAttributes().getAll();
- while (attrs.hasMore()) {
- // Open another connection to the LDAP server with the
found DN and the password
- searchEnv.put(Context.SECURITY_PRINCIPAL,
result.getNameInNamespace());
- searchEnv.put(Context.SECURITY_CREDENTIALS, userPwd);
- try {
- new InitialDirContext(searchEnv);
- } catch (Exception e) {
- log.warn("invalid ldap credentials or ldap search
error", e);
- return null;
- }
- Attribute attr = attrs.next();
- if (attr.getID().equals(ldapEmailAttribute)) {
- return (String) attr.get();
- }
+ EqualsFilter userFilter = new
EqualsFilter(ldapUserIdentifyingAttribute, userName);
+ String userSearchEmail = ldapSearch(ctx, null, userPwd,
userFilter.toString(), sc, searchEnv);
+
+ if (StringUtils.isNotEmpty(ldapAdminUserFilter)) {
+ String adminFilterSearchEmail = ldapSearch(ctx, userName,
userPwd, ldapAdminUserFilter, sc, searchEnv);
+ if (adminFilterSearchEmail != null) {
+ ldapLoginResult.setLdapEmail(adminFilterSearchEmail);
+ ldapLoginResult.setUserType(UserType.ADMIN_USER);
+ ldapLoginResult.setUserName(userName);
+ ldapLoginResult.setSuccess(true);
+ return ldapLoginResult;
}
+ } else {
+ log.debug("ldap admin user filter is empty, skipping admin
user filter search");
+ }
+
+ if (userSearchEmail != null) {
+ if (Objects.equals(ldapAdminUserName, userName)) {
+ ldapLoginResult.setUserType(UserType.ADMIN_USER);
+ } else {
+ ldapLoginResult.setUserType(UserType.GENERAL_USER);
+ }
+
+ ldapLoginResult.setLdapEmail(userSearchEmail);
+ ldapLoginResult.setUserName(userName);
+ ldapLoginResult.setSuccess(true);
+ return ldapLoginResult;
+ } else {
+ log.debug("user email attribute {} not found in ldap",
ldapEmailAttribute);
}
} catch (NamingException e) {
log.error("ldap search error", e);
- return null;
+ return ldapLoginResult;
} finally {
try {
if (ctx != null) {
@@ -139,7 +146,7 @@ public class LdapService {
}
}
- return null;
+ return ldapLoginResult;
}
/***
@@ -152,7 +159,7 @@ public class LdapService {
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, ldapSecurityPrincipal);
env.put(Context.SECURITY_CREDENTIALS, ldapPrincipalPassword);
- env.put(Context.PROVIDER_URL, ldapUrls);
+ env.put(Context.PROVIDER_URL, ldapUrl);
if (sslEnable) {
env.put(Context.SECURITY_PROTOCOL, "ssl");
@@ -164,6 +171,42 @@ public class LdapService {
return env;
}
+ private String ldapSearch(LdapContext ctx,
+ String userName,
+ String userPwd,
+ String filter,
+ SearchControls sc,
+ Properties searchEnv) throws NamingException {
+ NamingEnumeration<SearchResult> results;
+ if (userName == null) {
+ results = ctx.search(ldapBaseDn, filter, sc);
+ } else {
+ results = ctx.search(ldapBaseDn, filter, new Object[]{userName},
sc);
+ }
+ if (results.hasMore()) {
+ // get the users DN (distinguishedName) from the result
+ SearchResult result = results.next();
+ NamingEnumeration<? extends Attribute> attrs =
result.getAttributes().getAll();
+ while (attrs.hasMore()) {
+ // Open another connection to the LDAP server with the found
DN and the password
+ searchEnv.put(Context.SECURITY_PRINCIPAL,
result.getNameInNamespace());
+ searchEnv.put(Context.SECURITY_CREDENTIALS, userPwd);
+ try {
+ new InitialDirContext(searchEnv);
+ } catch (Exception e) {
+ log.warn("invalid ldap credentials or ldap search error",
e);
+ return null;
+ }
+ Attribute attr = attrs.next();
+ if (attr.getID().equals(ldapEmailAttribute)) {
+ return (String) attr.get();
+ }
+ }
+ }
+
+ return null;
+ }
+
public LdapUserNotExistActionType getLdapUserNotExistAction() {
if (StringUtils.isBlank(ldapUserNotExistAction)) {
log.info(
diff --git
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/pwd/PasswordAuthenticator.java
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/pwd/PasswordAuthenticator.java
index a7ae0dd9f1..86c419a605 100644
---
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/pwd/PasswordAuthenticator.java
+++
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/pwd/PasswordAuthenticator.java
@@ -23,7 +23,7 @@ import org.apache.dolphinscheduler.dao.entity.User;
public class PasswordAuthenticator extends AbstractAuthenticator {
@Override
- public User login(String userId, String password) {
- return userService.queryUser(userId, password);
+ public User login(String userName, String password) {
+ return userService.queryUser(userName, password);
}
}
diff --git
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/sso/CasdoorAuthenticator.java
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/sso/CasdoorAuthenticator.java
index 4d8cf93ada..5713696f8e 100644
---
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/sso/CasdoorAuthenticator.java
+++
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/sso/CasdoorAuthenticator.java
@@ -48,7 +48,7 @@ public class CasdoorAuthenticator extends
AbstractSsoAuthenticator {
private String adminUserName;
@Override
- public User login(@NonNull String state, String code) {
+ public User login(@NonNull String userName, String code) {
ServletRequestAttributes servletRequestAttributes =
(ServletRequestAttributes)
RequestContextHolder.getRequestAttributes();
if (servletRequestAttributes == null) {
@@ -59,11 +59,11 @@ public class CasdoorAuthenticator extends
AbstractSsoAuthenticator {
// Invalid state
request.getSession().setAttribute(Constants.SSO_LOGIN_USER_STATE,
null);
// Check state to protect from CSRF attack
- if (originalState == null ||
!MessageDigest.isEqual(originalState.getBytes(), state.getBytes())) {
+ if (originalState == null ||
!MessageDigest.isEqual(originalState.getBytes(), userName.getBytes())) {
return null;
}
- String token = casdoorAuthService.getOAuthToken(code, state);
+ String token = casdoorAuthService.getOAuthToken(code, userName);
CasdoorUser casdoorUser = casdoorAuthService.parseJwtToken(token);
User user = null;
if (casdoorUser.getName() != null) {
diff --git a/dolphinscheduler-api/src/main/resources/application.yaml
b/dolphinscheduler-api/src/main/resources/application.yaml
index 9b0e94d644..4578aa08ac 100644
--- a/dolphinscheduler-api/src/main/resources/application.yaml
+++ b/dolphinscheduler-api/src/main/resources/application.yaml
@@ -175,17 +175,19 @@ security:
# IF you set type `LDAP`, below config will be effective
ldap:
# ldap server config
- urls: ldap://ldap.forumsys.com:389/
+ url: ldap://ldap.forumsys.com:389/
base-dn: dc=example,dc=com
- username: cn=read-only-admin,dc=example,dc=com
+ username: cn=admin,dc=example,dc=com
password: password
user:
- # admin userId when you use LDAP login
- admin: read-only-admin
+ # admin username when you use LDAP login
+ admin-username: ldap-admin
+ # user search filter to find admin user
+ admin-user-filter: (&(cn={0}))
identity-attribute: uid
email-attribute: mail
# action when ldap user is not exist (supported types: CREATE,DENY)
- not-exist-action: CREATE
+ not-exist-action: DENY
ssl:
enable: false
# jks file absolute path && password
diff --git
a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/security/SecurityConfigLDAPTest.java
b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/security/SecurityConfigLDAPTest.java
index 88662273ea..ea09ec5a22 100644
---
a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/security/SecurityConfigLDAPTest.java
+++
b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/security/SecurityConfigLDAPTest.java
@@ -27,6 +27,7 @@ import org.springframework.test.context.TestPropertySource;
@TestPropertySource(properties = {
"security.authentication.type=LDAP",
+ "security.authentication.ldap.user.not-exist-action=CREATE"
})
public class SecurityConfigLDAPTest extends AbstractControllerTest {
diff --git
a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/security/impl/ldap/LdapAuthenticatorTest.java
b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/security/impl/ldap/LdapAuthenticatorTest.java
index 26f086a907..9e75634bcc 100644
---
a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/security/impl/ldap/LdapAuthenticatorTest.java
+++
b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/security/impl/ldap/LdapAuthenticatorTest.java
@@ -21,6 +21,7 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import org.apache.dolphinscheduler.api.controller.AbstractControllerTest;
+import org.apache.dolphinscheduler.api.dto.LdapLoginResult;
import org.apache.dolphinscheduler.api.enums.Status;
import org.apache.dolphinscheduler.api.security.LdapUserNotExistActionType;
import org.apache.dolphinscheduler.api.service.SessionService;
@@ -81,11 +82,13 @@ public class LdapAuthenticatorTest extends
AbstractControllerTest {
private User mockUser;
private Session mockSession;
- private String ldapUid = "test";
- private String ldapUserPwd = "password";
- private String ldapEmail = "[email protected]";
- private String ip = "127.0.0.1";
- private UserType userType = UserType.GENERAL_USER;
+ private final String ldapUid = "test";
+ private final String ldapUserPwd = "password";
+ private final String ldapEmail = "[email protected]";
+ private final String ip = "127.0.0.1";
+ private final UserType userType = UserType.GENERAL_USER;
+ private final LdapLoginResult ldapLoginResultSuccess = new
LdapLoginResult(true, ldapEmail, userType, ldapUid);
+ private final LdapLoginResult ldapLoginResultFailed = new
LdapLoginResult(false, ldapEmail, userType, ldapUid);
@Override
@BeforeEach
@@ -109,7 +112,7 @@ public class LdapAuthenticatorTest extends
AbstractControllerTest {
@Test
public void testAuthenticate() {
- when(ldapService.ldapLogin(ldapUid,
ldapUserPwd)).thenReturn(ldapEmail);
+ when(ldapService.ldapLogin(ldapUid,
ldapUserPwd)).thenReturn(ldapLoginResultSuccess);
when(sessionService.createSessionIfAbsent(Mockito.any(User.class))).thenReturn(mockSession);
// test username pwd correct and user not exist, config user not exist
action deny, so login denied
@@ -131,8 +134,9 @@ public class LdapAuthenticatorTest extends
AbstractControllerTest {
Assertions.assertEquals(Status.LOGIN_SESSION_FAILED.getCode(), (int)
result.getCode());
// test username pwd error, login failed
- when(ldapService.ldapLogin(ldapUid, ldapUserPwd)).thenReturn(null);
- result = ldapAuthenticator.authenticate(ldapUid, ldapUserPwd, ip);
+
when(sessionService.createSessionIfAbsent(Mockito.any(User.class))).thenReturn(mockSession);
+ when(ldapService.ldapLogin(ldapUid,
"123")).thenReturn(ldapLoginResultFailed);
+ result = ldapAuthenticator.authenticate(ldapUid, "123", ip);
Assertions.assertEquals(Status.USER_NAME_PASSWD_ERROR.getCode(), (int)
result.getCode());
}
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
deleted file mode 100644
index 30dbd80479..0000000000
---
a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/security/impl/ldap/LdapServiceTest.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.dolphinscheduler.api.security.impl.ldap;
-
-import org.apache.dolphinscheduler.api.ApiApplicationServer;
-import org.apache.dolphinscheduler.common.enums.ProfileType;
-import org.apache.dolphinscheduler.common.enums.UserType;
-
-import java.lang.reflect.Field;
-
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Disabled;
-import org.junit.jupiter.api.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.context.ActiveProfiles;
-import org.springframework.test.context.TestPropertySource;
-
-@Disabled
-@ActiveProfiles(ProfileType.H2)
-@SpringBootTest(classes = ApiApplicationServer.class)
-@TestPropertySource(properties = {
- "security.authentication.type=LDAP",
- "security.authentication.ldap.user.admin=read-only-admin",
- "security.authentication.ldap.urls=ldap://ldap.forumsys.com:389/",
- "security.authentication.ldap.base-dn=dc=example,dc=com",
-
"security.authentication.ldap.username=cn=read-only-admin,dc=example,dc=com",
- "security.authentication.ldap.password=password",
- "security.authentication.ldap.user.identity-attribute=uid",
- "security.authentication.ldap.user.email-attribute=mail",
- "security.authentication.ldap.user.not-exist-action=CREATE",
- "security.authentication.ldap.ssl.enable=false",
- "security.authentication.ldap.ssl.trust-store=",
- "security.authentication.ldap.ssl.trust-store-password=",
-})
-public class LdapServiceTest {
-
- @Autowired
- protected AutowireCapableBeanFactory beanFactory;
-
- private LdapService ldapService;
-
- private final String username = "tesla";
- private final String correctPassword = "password";
-
- @BeforeEach
- public void setUp() {
- ldapService = new LdapService();
- beanFactory.autowireBean(ldapService);
- }
-
- @Test
- public void getUserType() {
- UserType userType = ldapService.getUserType("read-only-admin");
- Assertions.assertEquals(UserType.ADMIN_USER, userType);
- }
-
- @Test
- public void ldapLogin() throws NoSuchFieldException,
IllegalAccessException {
- changeSslEnable(false);
- String email = ldapService.ldapLogin(username, correctPassword);
- Assertions.assertEquals("[email protected]", email);
- }
-
- @Test
- public void ldapLoginError() throws NoSuchFieldException,
IllegalAccessException {
- changeSslEnable(false);
- String email2 = ldapService.ldapLogin(username, "error password");
- Assertions.assertNull(email2);
- }
-
- @Test
- public void ldapLoginSSL() throws NoSuchFieldException,
IllegalAccessException {
- changeSslEnable(true);
- String email = ldapService.ldapLogin(username, correctPassword);
- Assertions.assertNull(email);
- }
-
- private void changeSslEnable(boolean sslEnable) throws
NoSuchFieldException, IllegalAccessException {
- Class<LdapService> ldapServiceClass = LdapService.class;
- Field sslEnableField = ldapServiceClass.getDeclaredField("sslEnable");
- sslEnableField.setAccessible(true);
- sslEnableField.set(ldapService, sslEnable);
- if (sslEnable) {
- Field trustStorePasswordField =
ldapServiceClass.getDeclaredField("trustStorePassword");
- trustStorePasswordField.setAccessible(true);
- trustStorePasswordField.set(ldapService, "trustStorePassword");
- }
- }
-}
diff --git a/dolphinscheduler-api/src/test/resources/application.yaml
b/dolphinscheduler-api/src/test/resources/application.yaml
index 5eb7e1f8d7..b5c3373d65 100644
--- a/dolphinscheduler-api/src/test/resources/application.yaml
+++ b/dolphinscheduler-api/src/test/resources/application.yaml
@@ -100,17 +100,18 @@ security:
# IF you set type `LDAP`, below config will be effective
ldap:
# ldap server config
- urls: ldap://ldap.forumsys.com:389/
+ url: ldap://ldap.forumsys.com:389/
base-dn: dc=example,dc=com
username: cn=read-only-admin,dc=example,dc=com
password: password
user:
- # admin userId when you use LDAP login
- admin: read-only-admin
+ # admin username when you use LDAP login
+ admin-username: admin
+ admin-user-filter: (&(cn={0}))
identity-attribute: uid
email-attribute: mail
# action when ldap user is not exist (supported types: CREATE,DENY)
- not-exist-action: CREATE
+ not-exist-action: DENY
ssl:
enable: false
# jks file absolute path && password
diff --git
a/dolphinscheduler-standalone-server/src/main/resources/application.yaml
b/dolphinscheduler-standalone-server/src/main/resources/application.yaml
index 97b9b6d22d..5f83729bad 100644
--- a/dolphinscheduler-standalone-server/src/main/resources/application.yaml
+++ b/dolphinscheduler-standalone-server/src/main/resources/application.yaml
@@ -90,17 +90,19 @@ security:
# IF you set type `LDAP`, below config will be effective
ldap:
# ldap server config
- urls: ldap://ldap.forumsys.com:389/
+ url: ldap://ldap.forumsys.com:389/
base-dn: dc=example,dc=com
- username: cn=read-only-admin,dc=example,dc=com
+ username: admin,dc=example,dc=com
password: password
user:
- # admin userId when you use LDAP login
- admin: read-only-admin
+ # admin username when you use LDAP login
+ admin-username: ldap-admin
+ # user search filter to find admin user
+ admin-user-filter: (&(cn={0}))
identity-attribute: uid
email-attribute: mail
# action when ldap user is not exist (supported types: CREATE,DENY)
- not-exist-action: CREATE
+ not-exist-action: DENY
ssl:
enable: false
# jks file absolute path && password