This is an automated email from the ASF dual-hosted git repository.
arshad pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/seatunnel-web.git
The following commit(s) were added to refs/heads/main by this push:
new 90d05b03 [LDAP] Add LDAP Authentication Provider Support. (#269)
90d05b03 is described below
commit 90d05b035764ca439f2887d8227cceb1335e5892
Author: Shashwat Tiwari <[email protected]>
AuthorDate: Fri Jan 17 18:47:32 2025 +0530
[LDAP] Add LDAP Authentication Provider Support. (#269)
Co-authored-by: BilwaST <[email protected]>
---
README.md | 26 ++++++++
README_CN.md | 25 +++++++-
pom.xml | 11 ++++
seatunnel-server/seatunnel-app/pom.xml | 9 +++
.../org/apache/seatunnel/app/common/Constants.java | 3 +
.../app/config/LdapAuthenticationBuilder.java | 74 ++++++++++++++++++++++
.../SeatunnelAuthenticationProvidersConfig.java} | 25 +++-----
.../SeatunnelLdapAuthenticationProvider.java | 64 +++++++++++++++++++
.../seatunnel/app/controller/UserController.java | 7 +-
.../org/apache/seatunnel/app/dal/dao/IUserDao.java | 2 +-
.../seatunnel/app/dal/dao/impl/UserDaoImpl.java | 5 +-
.../org/apache/seatunnel/app/dal/entity/User.java | 2 +
.../seatunnel/app/dal/mapper/UserMapper.java | 4 +-
.../app/domain/dto/user/UpdateUserDto.java | 1 +
.../strategy/IAuthenticationStrategy.java} | 17 ++---
.../strategy/impl/DBAuthenticationStrategy.java | 54 ++++++++++++++++
.../strategy/impl/LDAPAuthenticationStrategy.java | 68 ++++++++++++++++++++
.../apache/seatunnel/app/service/IUserService.java | 2 +-
.../app/service/impl/UserServiceImpl.java | 53 ++++++++++++----
.../src/main/resources/application.yml | 12 +++-
.../apache/seatunnel/app/dal/mapper/UserMapper.xml | 10 +--
.../main/resources/script/seatunnel_server_h2.sql | 1 +
.../resources/script/seatunnel_server_mysql.sql | 1 +
.../server/common/SeatunnelErrorEnum.java | 4 ++
.../app/common/SeatunnelWebTestingBase.java | 26 +++++++-
.../seatunnel/app/test/UserControllerTest.java | 60 ++++++++++++++++--
.../src/test/resources/application.yml | 10 +++
tools/dependencies/known-dependencies.txt | 4 ++
28 files changed, 519 insertions(+), 61 deletions(-)
diff --git a/README.md b/README.md
index 28e06a61..30a1aada 100644
--- a/README.md
+++ b/README.md
@@ -238,3 +238,29 @@ NOTE: This feature is currently useful when execution is
done through the API. T
Execute the following SQL to upgrade the database:
```ALTER TABLE `t_st_job_instance` ADD COLUMN `error_message` varchar(4096)
CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL;```
+
+#### 2. Upgrade from 1.0.2 or before to 1.0.3 or after.
+- Execute the following SQL to upgrade the database:
+ ```
+ ALTER TABLE `user` ADD COLUMN `auth_provider` varchar(10) CHARACTER SET
utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT 'DB';
+ ```
+- Enabling LDAP Support,
+ - For LDAP support, you need to add the LDAP server configurations and
include LDAP in the list of authentication providers in the application.yml
file.
+ - If no authentication providers are defined, default DB strategy will be
used, and no changes are required.
+ - Below is a sample configuration for both the authentication providers and
LDAP server settings.
+ ```
+ # sample application.yaml
+ spring:
+ ldap:
+ url: ldap://localhost:389
+ search:
+ base: ou=people,dc=example,dc=com
+ filter: (uid={0})
+ domain: example.com
+ seatunnel:
+ authentication:
+ providers:
+ - DB
+ - LDAP
+ ```
+
diff --git a/README_CN.md b/README_CN.md
index 8be3e6ab..e221ecc1 100644
--- a/README_CN.md
+++ b/README_CN.md
@@ -231,4 +231,27 @@ sh bin/seatunnel-backend-daemon.sh start
```ALTER TABLE `t_st_job_instance` ADD COLUMN `error_message` varchar(4096)
CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL;```
-
+#### 2. 从1.0.2或更早版本升级到1.0.3或更高版本。
+- 执行以下SQL语句以升级数据库:
+ ```
+ ALTER TABLE `user` ADD COLUMN `auth_provider` varchar(10) CHARACTER SET
utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT 'DB';
+ ```
+- 启用LDAP支持,
+ - 要启用LDAP支持,您需要在`application.yml`文件中添加LDAP服务器配置,并将LDAP包含在认证提供者列表中。
+ - 如果未定义任何认证提供者,将使用默认的DB策略,不需要做任何更改。
+ - 以下是认证提供者和LDAP服务器设置的示例配置。
+ ```
+ # sample application.yaml
+ spring:
+ ldap:
+ url: ldap://localhost:389
+ search:
+ base: ou=people,dc=example,dc=com
+ filter: (uid={0})
+ domain: example.com
+ seatunnel:
+ authentication:
+ providers:
+ - DB
+ - LDAP
+ ```
diff --git a/pom.xml b/pom.xml
index 3b064bad..852f2f30 100644
--- a/pom.xml
+++ b/pom.xml
@@ -90,6 +90,7 @@
<spring-boot.version>2.6.8</spring-boot.version>
<spring.version>5.3.20</spring.version>
+ <spring.security.version>5.6.5</spring.security.version>
<mybatis-plus-boot-starter.version>3.5.3.1</mybatis-plus-boot-starter.version>
<druid-spring-boot-starter.version>1.2.9</druid-spring-boot-starter.version>
<springfox-swagger.version>2.6.1</springfox-swagger.version>
@@ -349,6 +350,16 @@
<artifactId>spring-boot-starter-jdbc</artifactId>
<version>${spring-boot.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.springframework.security</groupId>
+ <artifactId>spring-security-core</artifactId>
+ <version>${spring.security.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.security</groupId>
+ <artifactId>spring-security-ldap</artifactId>
+ <version>${spring.security.version}</version>
+ </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
diff --git a/seatunnel-server/seatunnel-app/pom.xml
b/seatunnel-server/seatunnel-app/pom.xml
index 24c2a44f..98d93670 100644
--- a/seatunnel-server/seatunnel-app/pom.xml
+++ b/seatunnel-server/seatunnel-app/pom.xml
@@ -310,6 +310,15 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.springframework.security</groupId>
+ <artifactId>spring-security-core</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.springframework.security</groupId>
+ <artifactId>spring-security-ldap</artifactId>
+ </dependency>
<dependency>
<groupId>com.baomidou</groupId>
diff --git
a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/common/Constants.java
b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/common/Constants.java
index b32c48ed..886c1f70 100644
---
a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/common/Constants.java
+++
b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/common/Constants.java
@@ -655,4 +655,7 @@ public final class Constants {
public static final int DEFAULT_ALERT_GROUP_ID = 1;
public static final String TASK_ID = "taskId";
+
+ public static final String AUTHENTICATION_PROVIDER_LDAP = "LDAP";
+ public static final String AUTHENTICATION_PROVIDER_DB = "DB";
}
diff --git
a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/config/LdapAuthenticationBuilder.java
b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/config/LdapAuthenticationBuilder.java
new file mode 100644
index 00000000..a69e9c63
--- /dev/null
+++
b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/config/LdapAuthenticationBuilder.java
@@ -0,0 +1,74 @@
+/*
+ * 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.seatunnel.app.config;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.ldap.core.support.LdapContextSource;
+import
org.springframework.ldap.core.support.SimpleDirContextAuthenticationStrategy;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.ldap.DefaultSpringSecurityContextSource;
+import org.springframework.security.ldap.authentication.BindAuthenticator;
+import
org.springframework.security.ldap.authentication.LdapAuthenticationProvider;
+import org.springframework.security.ldap.search.FilterBasedLdapUserSearch;
+import org.springframework.stereotype.Component;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@Component
+public class LdapAuthenticationBuilder {
+
+ @Value("${spring.ldap.url}")
+ private String ldapUrl;
+
+ @Value("${spring.ldap.search.base}")
+ private String ldapSearchBase;
+
+ @Value("${spring.ldap.search.domain}")
+ private String ldapSearchDomain;
+
+ public LdapAuthenticationProvider buildLdapAuthenticationProvider(
+ Authentication authentication) {
+
+ LdapContextSource ldapContextSource = new
DefaultSpringSecurityContextSource(ldapUrl);
+ String ldapBindUser = authentication.getName();
+ ldapContextSource.setUserDn(
+ new StringBuilder()
+ .append(ldapBindUser)
+ .append("@")
+ .append(ldapSearchDomain)
+ .toString());
+
ldapContextSource.setPassword(authentication.getCredentials().toString());
+ ldapContextSource.setCacheEnvironmentProperties(false);
+ ldapContextSource.setAuthenticationStrategy(new
SimpleDirContextAuthenticationStrategy());
+ ldapContextSource.afterPropertiesSet();
+
+ String ldapAuthID =
+ ldapBindUser.toLowerCase().endsWith("@" + ldapSearchDomain)
+ ? ldapBindUser
+ : ldapBindUser + "@" + ldapSearchDomain;
+ String searchFilter = "(userPrincipalName=" + ldapAuthID + ")";
+ FilterBasedLdapUserSearch userSearch =
+ new FilterBasedLdapUserSearch(ldapSearchBase, searchFilter,
ldapContextSource);
+ userSearch.setSearchSubtree(true);
+ BindAuthenticator authenticator = new
BindAuthenticator(ldapContextSource);
+ authenticator.setUserSearch(userSearch);
+ LdapAuthenticationProvider ldapAuthenticationProvider =
+ new LdapAuthenticationProvider(authenticator);
+ return ldapAuthenticationProvider;
+ }
+}
diff --git
a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/entity/User.java
b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/config/SeatunnelAuthenticationProvidersConfig.java
similarity index 66%
copy from
seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/entity/User.java
copy to
seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/config/SeatunnelAuthenticationProvidersConfig.java
index 73777653..e1c52c43 100644
---
a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/entity/User.java
+++
b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/config/SeatunnelAuthenticationProvidersConfig.java
@@ -14,26 +14,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package org.apache.seatunnel.app.config;
-package org.apache.seatunnel.app.dal.entity;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
import lombok.Data;
-import java.util.Date;
+import java.util.ArrayList;
+import java.util.List;
@Data
-public class User {
- private Integer id;
-
- private String username;
-
- private String password;
-
- private Byte status;
-
- private Byte type;
-
- private Date createTime;
-
- private Date updateTime;
+@Configuration
+@ConfigurationProperties(prefix = "spring.authentication")
+public class SeatunnelAuthenticationProvidersConfig {
+ private List<String> providers = new ArrayList<>();
}
diff --git
a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/config/SeatunnelLdapAuthenticationProvider.java
b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/config/SeatunnelLdapAuthenticationProvider.java
new file mode 100644
index 00000000..84694361
--- /dev/null
+++
b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/config/SeatunnelLdapAuthenticationProvider.java
@@ -0,0 +1,64 @@
+/*
+ * 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.seatunnel.app.config;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.authentication.AuthenticationProvider;
+import org.springframework.security.authentication.BadCredentialsException;
+import
org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
+import
org.springframework.security.ldap.authentication.LdapAuthenticationProvider;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Configuration
+@Slf4j
+public class SeatunnelLdapAuthenticationProvider implements
AuthenticationProvider {
+
+ @Autowired LdapAuthenticationBuilder ldapAuthenticationBuilder;
+
+ @Override
+ public boolean supports(Class<?> authentication) {
+ return
(UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
+ }
+
+ @Override
+ public Authentication authenticate(Authentication authentication)
+ throws AuthenticationException {
+ try {
+ LdapAuthenticationProvider ldapAuthenticationProvider =
+
ldapAuthenticationBuilder.buildLdapAuthenticationProvider(authentication);
+ return ldapAuthenticationProvider.authenticate(authentication);
+ } catch (BadCredentialsException ex) {
+ log.error("Invalid credentials for user : {}",
authentication.getName());
+ throw new BadCredentialsException("Invalid credentials");
+ } catch (Exception ex) {
+ log.error(
+ "Error while authenticating user : {}, reason :{}",
+ authentication.getName(),
+ ex.getMessage());
+ throw new AuthenticationException(ex.getMessage().toString()) {
+ @Override
+ public String getMessage() {
+ return super.getMessage();
+ }
+ };
+ }
+ }
+}
diff --git
a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/controller/UserController.java
b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/controller/UserController.java
index 106f23ff..59c68ab4 100644
---
a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/controller/UserController.java
+++
b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/controller/UserController.java
@@ -34,6 +34,7 @@ import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@@ -110,8 +111,10 @@ public class UserController {
}
@PostMapping("/login")
- public Result<UserSimpleInfoRes> login(@RequestBody UserLoginReq req) {
- return Result.success(iUserService.login(req));
+ public Result<UserSimpleInfoRes> login(
+ @RequestBody UserLoginReq req,
+ @RequestHeader(value = "X-Seatunnel-Auth-Type", required = false)
String authType) {
+ return Result.success(iUserService.login(req, authType));
}
@PatchMapping("/logout")
diff --git
a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/IUserDao.java
b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/IUserDao.java
index 8adb6442..be5dd16d 100644
---
a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/IUserDao.java
+++
b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/IUserDao.java
@@ -45,7 +45,7 @@ public interface IUserDao {
User getByName(String user);
- User checkPassword(String username, String password);
+ User checkPassword(String username, String password, String authProvider);
long insertLoginLog(UserLoginLogDto dto);
diff --git
a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/impl/UserDaoImpl.java
b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/impl/UserDaoImpl.java
index 0b26991d..3d1afef2 100644
---
a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/impl/UserDaoImpl.java
+++
b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/impl/UserDaoImpl.java
@@ -52,6 +52,7 @@ public class UserDaoImpl implements IUserDao {
user.setPassword(dto.getPassword());
user.setType((byte) dto.getType());
user.setStatus((byte) dto.getStatus());
+ user.setAuthProvider(dto.getAuthProvider());
userMapper.insert(user);
return user.getId();
@@ -114,8 +115,8 @@ public class UserDaoImpl implements IUserDao {
}
@Override
- public User checkPassword(String username, String password) {
- return userMapper.selectByNameAndPasswd(username, password);
+ public User checkPassword(String username, String password, String
authProvider) {
+ return userMapper.selectByNameAndPasswd(username, password,
authProvider);
}
@Override
diff --git
a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/entity/User.java
b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/entity/User.java
index 73777653..978360a0 100644
---
a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/entity/User.java
+++
b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/entity/User.java
@@ -36,4 +36,6 @@ public class User {
private Date createTime;
private Date updateTime;
+
+ private String authProvider;
}
diff --git
a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/mapper/UserMapper.java
b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/mapper/UserMapper.java
index 5d13b976..9648ecd9 100644
---
a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/mapper/UserMapper.java
+++
b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/mapper/UserMapper.java
@@ -44,7 +44,9 @@ public interface UserMapper {
int countBySelective(@Param("user") User user);
User selectByNameAndPasswd(
- @Param("username") String username, @Param("password") String
password);
+ @Param("username") String username,
+ @Param("password") String password,
+ @Param("authProvider") String authProvider);
List<User> queryEnabledUsers();
}
diff --git
a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/dto/user/UpdateUserDto.java
b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/dto/user/UpdateUserDto.java
index d65383ed..f4d430cd 100644
---
a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/dto/user/UpdateUserDto.java
+++
b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/dto/user/UpdateUserDto.java
@@ -28,4 +28,5 @@ public class UpdateUserDto {
private String password;
private int status;
private int type;
+ private String authProvider;
}
diff --git
a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/dto/user/UpdateUserDto.java
b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/security/authentication/strategy/IAuthenticationStrategy.java
similarity index 75%
copy from
seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/dto/user/UpdateUserDto.java
copy to
seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/security/authentication/strategy/IAuthenticationStrategy.java
index d65383ed..4e77c8ca 100644
---
a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/dto/user/UpdateUserDto.java
+++
b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/security/authentication/strategy/IAuthenticationStrategy.java
@@ -14,18 +14,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package org.apache.seatunnel.app.security.authentication.strategy;
-package org.apache.seatunnel.app.domain.dto.user;
+import org.apache.seatunnel.app.dal.entity.User;
+import org.apache.seatunnel.app.domain.request.user.UserLoginReq;
-import lombok.Builder;
-import lombok.Data;
-
-@Builder
-@Data
-public class UpdateUserDto {
- private Integer id;
- private String username;
- private String password;
- private int status;
- private int type;
+public interface IAuthenticationStrategy {
+ User authenticate(UserLoginReq req);
}
diff --git
a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/security/authentication/strategy/impl/DBAuthenticationStrategy.java
b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/security/authentication/strategy/impl/DBAuthenticationStrategy.java
new file mode 100644
index 00000000..eff7fa36
--- /dev/null
+++
b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/security/authentication/strategy/impl/DBAuthenticationStrategy.java
@@ -0,0 +1,54 @@
+/*
+ * 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.seatunnel.app.security.authentication.strategy.impl;
+
+import org.apache.seatunnel.app.common.Constants;
+import org.apache.seatunnel.app.dal.dao.IUserDao;
+import org.apache.seatunnel.app.dal.entity.User;
+import org.apache.seatunnel.app.domain.request.user.UserLoginReq;
+import
org.apache.seatunnel.app.security.authentication.strategy.IAuthenticationStrategy;
+import org.apache.seatunnel.app.utils.PasswordUtils;
+import org.apache.seatunnel.server.common.SeatunnelException;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.util.Objects;
+
+import static
org.apache.seatunnel.server.common.SeatunnelErrorEnum.USERNAME_PASSWORD_NO_MATCHED;
+
+@Component
+public class DBAuthenticationStrategy implements IAuthenticationStrategy {
+
+ @Autowired private IUserDao userDaoImpl;
+
+ @Value("${user.default.passwordSalt:seatunnel}")
+ private String defaultSalt;
+
+ @Override
+ public User authenticate(UserLoginReq req) {
+ final String password = PasswordUtils.encryptWithSalt(defaultSalt,
req.getPassword());
+ final User user =
+ userDaoImpl.checkPassword(
+ req.getUsername(), password,
Constants.AUTHENTICATION_PROVIDER_DB);
+ if (Objects.isNull(user)) {
+ throw new SeatunnelException(USERNAME_PASSWORD_NO_MATCHED);
+ }
+ return user;
+ }
+}
diff --git
a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/security/authentication/strategy/impl/LDAPAuthenticationStrategy.java
b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/security/authentication/strategy/impl/LDAPAuthenticationStrategy.java
new file mode 100644
index 00000000..1fa9bad5
--- /dev/null
+++
b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/security/authentication/strategy/impl/LDAPAuthenticationStrategy.java
@@ -0,0 +1,68 @@
+/*
+ * 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.seatunnel.app.security.authentication.strategy.impl;
+
+import org.apache.seatunnel.app.common.Constants;
+import org.apache.seatunnel.app.config.SeatunnelLdapAuthenticationProvider;
+import org.apache.seatunnel.app.dal.dao.IUserDao;
+import org.apache.seatunnel.app.dal.entity.User;
+import org.apache.seatunnel.app.domain.dto.user.UpdateUserDto;
+import org.apache.seatunnel.app.domain.request.user.UserLoginReq;
+import
org.apache.seatunnel.app.security.authentication.strategy.IAuthenticationStrategy;
+import org.apache.seatunnel.server.common.SeatunnelException;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import
org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.stereotype.Component;
+
+import static
org.apache.seatunnel.server.common.SeatunnelErrorEnum.USERNAME_PASSWORD_NO_MATCHED;
+
+@Component
+public class LDAPAuthenticationStrategy implements IAuthenticationStrategy {
+
+ @Autowired private IUserDao userDaoImpl;
+
+ @Autowired private SeatunnelLdapAuthenticationProvider
seatunnelLdapAuthenticationProvider;
+
+ @Override
+ public User authenticate(UserLoginReq req) {
+ String username = req.getUsername();
+ String password = req.getPassword();
+ Authentication authenticationRequest =
+ new UsernamePasswordAuthenticationToken(username, password);
+ try {
+
seatunnelLdapAuthenticationProvider.authenticate(authenticationRequest);
+ } catch (AuthenticationException ex) {
+ throw new SeatunnelException(USERNAME_PASSWORD_NO_MATCHED);
+ }
+
+ if (userDaoImpl.getByName(username) == null) {
+ // 2. add a new user.
+ final UpdateUserDto dto =
+ UpdateUserDto.builder()
+ .id(null)
+ .username(username)
+ .password("")
+
.authProvider(Constants.AUTHENTICATION_PROVIDER_LDAP)
+ .build();
+ userDaoImpl.add(dto);
+ }
+ return userDaoImpl.getByName(username);
+ }
+}
diff --git
a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/service/IUserService.java
b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/service/IUserService.java
index 60ba8d43..1b84559a 100644
---
a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/service/IUserService.java
+++
b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/service/IUserService.java
@@ -39,5 +39,5 @@ public interface IUserService {
void disable(int id);
- UserSimpleInfoRes login(UserLoginReq req);
+ UserSimpleInfoRes login(UserLoginReq req, String authType);
}
diff --git
a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/service/impl/UserServiceImpl.java
b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/service/impl/UserServiceImpl.java
index 95f2321f..853e6819 100644
---
a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/service/impl/UserServiceImpl.java
+++
b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/service/impl/UserServiceImpl.java
@@ -17,7 +17,9 @@
package org.apache.seatunnel.app.service.impl;
+import org.apache.seatunnel.app.common.Constants;
import org.apache.seatunnel.app.common.UserTokenStatusEnum;
+import org.apache.seatunnel.app.config.SeatunnelAuthenticationProvidersConfig;
import org.apache.seatunnel.app.dal.dao.IUserDao;
import org.apache.seatunnel.app.dal.entity.User;
import org.apache.seatunnel.app.domain.dto.user.ListUserDto;
@@ -31,24 +33,31 @@ import org.apache.seatunnel.app.domain.response.PageInfo;
import org.apache.seatunnel.app.domain.response.user.AddUserRes;
import org.apache.seatunnel.app.domain.response.user.UserSimpleInfoRes;
import org.apache.seatunnel.app.security.JwtUtils;
+import
org.apache.seatunnel.app.security.authentication.strategy.IAuthenticationStrategy;
+import
org.apache.seatunnel.app.security.authentication.strategy.impl.DBAuthenticationStrategy;
+import
org.apache.seatunnel.app.security.authentication.strategy.impl.LDAPAuthenticationStrategy;
import org.apache.seatunnel.app.service.IRoleService;
import org.apache.seatunnel.app.service.IUserService;
import org.apache.seatunnel.app.utils.PasswordUtils;
import org.apache.seatunnel.server.common.PageData;
+import org.apache.seatunnel.server.common.SeatunnelErrorEnum;
import org.apache.seatunnel.server.common.SeatunnelException;
+import org.apache.commons.lang3.StringUtils;
+
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
+import javax.annotation.PostConstruct;
import javax.annotation.Resource;
+import java.util.HashMap;
import java.util.List;
-import java.util.Objects;
+import java.util.Map;
import java.util.stream.Collectors;
-import static
org.apache.seatunnel.server.common.SeatunnelErrorEnum.USERNAME_PASSWORD_NO_MATCHED;
-
@Component
public class UserServiceImpl implements IUserService {
@Resource private IUserDao userDaoImpl;
@@ -60,6 +69,26 @@ public class UserServiceImpl implements IUserService {
@Value("${user.default.passwordSalt:seatunnel}")
private String defaultSalt;
+ private final Map<String, IAuthenticationStrategy> strategies = new
HashMap<>();
+
+ @Autowired private DBAuthenticationStrategy dbAuthenticationStrategy;
+
+ @Autowired private LDAPAuthenticationStrategy ldapAuthenticationStrategy;
+
+ @Autowired
+ private SeatunnelAuthenticationProvidersConfig
seatunnelAuthenticationProvidersConfig;
+
+ @PostConstruct
+ public void init() {
+ List<String> providers =
seatunnelAuthenticationProvidersConfig.getProviders();
+ if (providers.isEmpty() ||
providers.contains(Constants.AUTHENTICATION_PROVIDER_DB)) {
+ strategies.put(Constants.AUTHENTICATION_PROVIDER_DB,
dbAuthenticationStrategy);
+ }
+ if (providers.contains(Constants.AUTHENTICATION_PROVIDER_LDAP)) {
+ strategies.put(Constants.AUTHENTICATION_PROVIDER_LDAP,
ldapAuthenticationStrategy);
+ }
+ }
+
@Override
@Transactional(rollbackFor = Exception.class)
public AddUserRes add(AddUserReq addReq) {
@@ -75,6 +104,7 @@ public class UserServiceImpl implements IUserService {
.password(PasswordUtils.encryptWithSalt(defaultSalt,
addReq.getPassword()))
.status(addReq.getStatus())
.type(addReq.getType())
+ .authProvider(Constants.AUTHENTICATION_PROVIDER_DB)
.build();
final int userId = userDaoImpl.add(dto);
@@ -139,16 +169,14 @@ public class UserServiceImpl implements IUserService {
}
@Override
- public UserSimpleInfoRes login(UserLoginReq req) {
-
- final String username = req.getUsername();
- final String password = PasswordUtils.encryptWithSalt(defaultSalt,
req.getPassword());
-
- final User user = userDaoImpl.checkPassword(username, password);
- if (Objects.isNull(user)) {
- throw new SeatunnelException(USERNAME_PASSWORD_NO_MATCHED);
+ public UserSimpleInfoRes login(UserLoginReq req, String authType) {
+ authType = StringUtils.isEmpty(authType) ?
Constants.AUTHENTICATION_PROVIDER_DB : authType;
+ if (!strategies.containsKey(authType)) {
+ throw new SeatunnelException(
+ SeatunnelErrorEnum.INVALID_AUTHENTICATION_PROVIDER,
authType);
}
-
+ IAuthenticationStrategy strategy = strategies.get(authType);
+ User user = strategy.authenticate(req);
UserSimpleInfoRes translate = translate(user);
final String token = jwtUtils.genToken(translate.toMap());
translate.setToken(token);
@@ -160,7 +188,6 @@ public class UserServiceImpl implements IUserService {
.userId(user.getId())
.build();
userDaoImpl.insertLoginLog(logDto);
-
return translate;
}
diff --git a/seatunnel-server/seatunnel-app/src/main/resources/application.yml
b/seatunnel-server/seatunnel-app/src/main/resources/application.yml
index a85295a6..6a06d519 100644
--- a/seatunnel-server/seatunnel-app/src/main/resources/application.yml
+++ b/seatunnel-server/seatunnel-app/src/main/resources/application.yml
@@ -31,13 +31,23 @@ spring:
mvc:
pathmatch:
matching-strategy: ant_path_matcher
-
+ ldap:
+ url: ldap://localhost:389
+ search:
+ base: ou=people,dc=example,dc=com
+ filter: (uid={0})
+ domain: example.com
+ authentication:
+ providers:
+ - DB
+ #- LDAP # LDAP authentication is disabled by default
jwt:
expireTime: 86400
# please add key when deploy
secretKey:
algorithm: HS256
+
---
spring:
config:
diff --git
a/seatunnel-server/seatunnel-app/src/main/resources/org/apache/seatunnel/app/dal/mapper/UserMapper.xml
b/seatunnel-server/seatunnel-app/src/main/resources/org/apache/seatunnel/app/dal/mapper/UserMapper.xml
index 0539f9cc..f4e8abcb 100644
---
a/seatunnel-server/seatunnel-app/src/main/resources/org/apache/seatunnel/app/dal/mapper/UserMapper.xml
+++
b/seatunnel-server/seatunnel-app/src/main/resources/org/apache/seatunnel/app/dal/mapper/UserMapper.xml
@@ -23,6 +23,7 @@
<result column="type" jdbcType="TINYINT" property="type"/>
<result column="create_time" jdbcType="TIMESTAMP"
property="createTime"/>
<result column="update_time" jdbcType="TIMESTAMP"
property="updateTime"/>
+ <result column="auth_provider" jdbcType="VARCHAR"
property="authProvider"/>
</resultMap>
<sql id="Base_Column_List">
id,
@@ -31,13 +32,14 @@
`status`,
`type`,
create_time,
- update_time
+ update_time,
+ auth_provider
</sql>
<insert id="insert" keyColumn="id" keyProperty="id"
parameterType="org.apache.seatunnel.app.dal.entity.User"
useGeneratedKeys="true">
- insert into `user` (username, password, status, type)
+ insert into `user` (username, password, status, type, auth_provider)
values (#{username,jdbcType=VARCHAR},
#{password,jdbcType=VARCHAR}, #{status,jdbcType=TINYINT},
- #{type,jdbcType=TINYINT})
+ #{type,jdbcType=TINYINT},
#{authProvider,jdbcType=VARCHAR})
</insert>
<update id="updateByPrimaryKey">
update `user`
@@ -94,7 +96,7 @@
select
<include refid="Base_Column_List"/>
from `user`
- where username = #{username,jdbcType=VARCHAR} and password =
#{password,jdbcType=VARCHAR}
+ where username = #{username,jdbcType=VARCHAR} and password =
#{password,jdbcType=VARCHAR} and auth_provider =
#{authProvider,jdbcType=VARCHAR}
</select>
<select id="queryEnabledUsers"
resultType="org.apache.seatunnel.app.dal.entity.User">
select
diff --git
a/seatunnel-server/seatunnel-app/src/main/resources/script/seatunnel_server_h2.sql
b/seatunnel-server/seatunnel-app/src/main/resources/script/seatunnel_server_h2.sql
index f9bfb51a..b4231ce6 100644
---
a/seatunnel-server/seatunnel-app/src/main/resources/script/seatunnel_server_h2.sql
+++
b/seatunnel-server/seatunnel-app/src/main/resources/script/seatunnel_server_h2.sql
@@ -219,6 +219,7 @@ CREATE TABLE "user" (
type TINYINT NOT NULL,
create_time TIMESTAMP(3) NOT NULL DEFAULT
CURRENT_TIMESTAMP(3),
update_time TIMESTAMP(3) NOT NULL DEFAULT
CURRENT_TIMESTAMP(3),
+ auth_provider varchar(10) NOT NULL DEFAULT 'DB',
PRIMARY KEY (id)
);
diff --git
a/seatunnel-server/seatunnel-app/src/main/resources/script/seatunnel_server_mysql.sql
b/seatunnel-server/seatunnel-app/src/main/resources/script/seatunnel_server_mysql.sql
index 2fd44da2..2262caa6 100644
---
a/seatunnel-server/seatunnel-app/src/main/resources/script/seatunnel_server_mysql.sql
+++
b/seatunnel-server/seatunnel-app/src/main/resources/script/seatunnel_server_mysql.sql
@@ -235,6 +235,7 @@ CREATE TABLE `user` (
`type` tinyint(4) NOT NULL,
`create_time` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
`update_time` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE
CURRENT_TIMESTAMP(3),
+ `auth_provider` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci
NOT NULL DEFAULT 'DB',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE =
utf8mb4_general_ci ROW_FORMAT = Dynamic;
diff --git
a/seatunnel-server/seatunnel-server-common/src/main/java/org/apache/seatunnel/server/common/SeatunnelErrorEnum.java
b/seatunnel-server/seatunnel-server-common/src/main/java/org/apache/seatunnel/server/common/SeatunnelErrorEnum.java
index 83ba0a4e..29c772ac 100644
---
a/seatunnel-server/seatunnel-server-common/src/main/java/org/apache/seatunnel/server/common/SeatunnelErrorEnum.java
+++
b/seatunnel-server/seatunnel-server-common/src/main/java/org/apache/seatunnel/server/common/SeatunnelErrorEnum.java
@@ -36,6 +36,10 @@ public enum SeatunnelErrorEnum {
"The user name and password do not match, please check your
input"),
TOKEN_ILLEGAL(10008, "token illegal", "The token is expired or invalid,
please login again."),
+ INVALID_AUTHENTICATION_PROVIDER(
+ 10010,
+ "please provide the supported authentication providers, default
DB",
+ "Invalid authentication provider [%s]"),
NO_SUCH_JOB(10009, "no such job", "No such job. Maybe deleted by others."),
/** request dolphinscheduler failed */
diff --git
a/seatunnel-web-it/src/test/java/org/apache/seatunnel/app/common/SeatunnelWebTestingBase.java
b/seatunnel-web-it/src/test/java/org/apache/seatunnel/app/common/SeatunnelWebTestingBase.java
index fd17fbb5..a006cd31 100644
---
a/seatunnel-web-it/src/test/java/org/apache/seatunnel/app/common/SeatunnelWebTestingBase.java
+++
b/seatunnel-web-it/src/test/java/org/apache/seatunnel/app/common/SeatunnelWebTestingBase.java
@@ -31,13 +31,23 @@ import java.lang.reflect.Field;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import java.util.Map;
public class SeatunnelWebTestingBase {
protected final String baseUrl = "http://localhost:8802/seatunnel/api/v1";
- protected Result<UserSimpleInfoRes> login(UserLoginReq userLoginReq) {
+ public Result<UserSimpleInfoRes> login(UserLoginReq userLoginReq) {
+ return login(userLoginReq, null);
+ }
+
+ public Result<UserSimpleInfoRes> login(UserLoginReq userLoginReq, String
authType) {
String requestBody = JsonUtils.toJsonString(userLoginReq);
- String response = sendRequest(url("user/login"), requestBody, "POST");
+ Map<String, String> headers =
+ authType != null
+ ? Collections.singletonMap("X-Seatunnel-Auth-Type",
authType)
+ : null;
+ String response = sendRequest(url("user/login"), requestBody, "POST",
headers);
return JSONTestUtils.parseObject(
response, new TypeReference<Result<UserSimpleInfoRes>>() {});
}
@@ -51,10 +61,15 @@ public class SeatunnelWebTestingBase {
}
protected String sendRequest(String url) {
- return sendRequest(url, null, "GET");
+ return sendRequest(url, null, "GET", null);
}
protected String sendRequest(String url, String requestBody, String
httpMethod) {
+ return sendRequest(url, requestBody, httpMethod, null);
+ }
+
+ protected String sendRequest(
+ String url, String requestBody, String httpMethod, Map<String,
String> headers) {
HttpURLConnection connection = null;
try {
URL urlObject = new URL(url);
@@ -69,6 +84,11 @@ public class SeatunnelWebTestingBase {
if (!url.endsWith("user/login?")) {
connection.setRequestProperty("token",
TokenProvider.getToken());
}
+ if (headers != null && !headers.isEmpty()) {
+ for (Map.Entry<String, String> header : headers.entrySet()) {
+ connection.setRequestProperty(header.getKey(),
header.getValue());
+ }
+ }
connection.setDoOutput(true);
if (requestBody != null) {
try (OutputStream os = connection.getOutputStream()) {
diff --git
a/seatunnel-web-it/src/test/java/org/apache/seatunnel/app/test/UserControllerTest.java
b/seatunnel-web-it/src/test/java/org/apache/seatunnel/app/test/UserControllerTest.java
index f6e72857..76c28b37 100644
---
a/seatunnel-web-it/src/test/java/org/apache/seatunnel/app/test/UserControllerTest.java
+++
b/seatunnel-web-it/src/test/java/org/apache/seatunnel/app/test/UserControllerTest.java
@@ -21,19 +21,24 @@ import org.apache.seatunnel.app.common.SeaTunnelWebCluster;
import org.apache.seatunnel.app.controller.UserControllerWrapper;
import org.apache.seatunnel.app.domain.request.user.AddUserReq;
import org.apache.seatunnel.app.domain.request.user.UpdateUserReq;
+import org.apache.seatunnel.app.domain.request.user.UserLoginReq;
import org.apache.seatunnel.app.domain.response.user.AddUserRes;
+import org.apache.seatunnel.app.domain.response.user.UserSimpleInfoRes;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
+import java.util.function.Supplier;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class UserControllerTest {
private static final SeaTunnelWebCluster seaTunnelWebCluster = new
SeaTunnelWebCluster();
private static UserControllerWrapper userControllerWrapper;
- private static String uniqueId = "_" + System.currentTimeMillis();
+ final Supplier<String> uniqueId = () -> "_" + System.nanoTime();
@BeforeAll
public static void setUp() {
@@ -43,7 +48,7 @@ public class UserControllerTest {
@Test
public void addUser_shouldReturnSuccess_whenValidRequest() {
- String user = "addUser" + uniqueId;
+ String user = "addUser" + uniqueId.get();
AddUserReq addUserReq = getAddUserReq(user, "pass1");
Result<AddUserRes> result = userControllerWrapper.addUser(addUserReq);
assertTrue(result.isSuccess());
@@ -61,7 +66,7 @@ public class UserControllerTest {
@Test
public void updateUser_shouldReturnSuccess_whenValidRequest() {
- String user = "updateUser" + uniqueId;
+ String user = "updateUser" + uniqueId.get();
AddUserReq addUserReq = getAddUserReq(user, "pass2");
Result<AddUserRes> result = userControllerWrapper.addUser(addUserReq);
assertTrue(result.isSuccess());
@@ -79,7 +84,7 @@ public class UserControllerTest {
@Test
public void deleteUser_shouldReturnSuccess_whenValidUserId() {
- String user = "deleteUser" + uniqueId;
+ String user = "deleteUser" + uniqueId.get();
AddUserReq addUserReq = getAddUserReq(user, "pass3");
Result<AddUserRes> result = userControllerWrapper.addUser(addUserReq);
assertTrue(result.isSuccess());
@@ -95,6 +100,53 @@ public class UserControllerTest {
assertNotNull(result.getData());
}
+ @Test
+ public void login_shouldPass_whenValidAuthType() {
+ String user = "loginUser" + uniqueId.get();
+ AddUserReq addUserReq = getAddUserReq(user, "pass4");
+ Result<AddUserRes> addUserResult =
userControllerWrapper.addUser(addUserReq);
+ assertTrue(addUserResult.isSuccess());
+
+ UserLoginReq loginReq = new UserLoginReq();
+ loginReq.setUsername(user);
+ loginReq.setPassword("pass4");
+
+ Result<UserSimpleInfoRes> loginResult =
userControllerWrapper.login(loginReq, "DB");
+ assertTrue(loginResult.isSuccess());
+ }
+
+ @Test
+ public void login_shouldPass_whenNoAuthType() {
+ String user = "loginUser" + uniqueId.get();
+ AddUserReq addUserReq = getAddUserReq(user, "pass5");
+ Result<AddUserRes> addUserResult =
userControllerWrapper.addUser(addUserReq);
+ assertTrue(addUserResult.isSuccess());
+
+ UserLoginReq loginReq = new UserLoginReq();
+ loginReq.setUsername(user);
+ loginReq.setPassword("pass5");
+
+ Result<UserSimpleInfoRes> loginResult =
userControllerWrapper.login(loginReq);
+ assertTrue(loginResult.isSuccess());
+ }
+
+ @Test
+ public void login_shouldFail_whenInvalidAuthType() {
+ String user = "loginUser" + uniqueId.get();
+ AddUserReq addUserReq = getAddUserReq(user, "pass6");
+ Result<AddUserRes> addUserResult =
userControllerWrapper.addUser(addUserReq);
+ assertTrue(addUserResult.isSuccess());
+
+ UserLoginReq loginReq = new UserLoginReq();
+ loginReq.setUsername(user);
+ loginReq.setPassword("pass6");
+
+ Result<UserSimpleInfoRes> loginResult =
+ userControllerWrapper.login(loginReq, "INVALID_AUTH_TYPE");
+ assertTrue(loginResult.isFailed());
+ assertEquals("Invalid authentication provider [INVALID_AUTH_TYPE]",
loginResult.getMsg());
+ }
+
@AfterAll
public static void tearDown() {
Result<Void> logout = userControllerWrapper.logout();
diff --git a/seatunnel-web-it/src/test/resources/application.yml
b/seatunnel-web-it/src/test/resources/application.yml
index 276983f3..ef285655 100644
--- a/seatunnel-web-it/src/test/resources/application.yml
+++ b/seatunnel-web-it/src/test/resources/application.yml
@@ -31,6 +31,16 @@ spring:
mvc:
pathmatch:
matching-strategy: ant_path_matcher
+ ldap:
+ url: ldap://localhost:389
+ search:
+ base: ou=people,dc=example,dc=com
+ filter: (uid={0})
+ domain: example.com
+ authentication:
+ providers:
+ - DB
+ #- LDAP # LDAP authentication is disabled by default
jwt:
expireTime: 86400
diff --git a/tools/dependencies/known-dependencies.txt
b/tools/dependencies/known-dependencies.txt
index a9d1ec32..2e110bef 100644
--- a/tools/dependencies/known-dependencies.txt
+++ b/tools/dependencies/known-dependencies.txt
@@ -74,8 +74,12 @@ spring-core-5.3.20.jar
spring-expression-5.3.20.jar
spring-jcl-5.3.20.jar
spring-jdbc-5.3.20.jar
+spring-ldap-core-2.3.7.RELEASE.jar
spring-plugin-core-1.2.0.RELEASE.jar
spring-plugin-metadata-1.2.0.RELEASE.jar
+spring-security-core-5.6.5.jar
+spring-security-ldap-5.6.5.jar
+spring-security-crypto-5.6.5.jar
spring-tx-5.3.20.jar
spring-web-5.3.20.jar
spring-webmvc-5.3.20.jar