Merge e7a598bef6 into d8011d857a
This commit is contained in:
commit
3f3a034056
|
|
@ -242,43 +242,45 @@ The default configuration is as follows:
|
|||
|
||||
Location: `api-server/conf/application.yaml`
|
||||
|
||||
| Parameters | Default value | Description |
|
||||
|-------------------------------------------------------|--------------------------------------|------------------------------------------------------------------------------------------------|
|
||||
| server.port | 12345 | api service communication port |
|
||||
| server.servlet.session.timeout | 120m | session timeout |
|
||||
| server.servlet.context-path | /dolphinscheduler/ | request path |
|
||||
| spring.servlet.multipart.max-file-size | 1024MB | maximum file size |
|
||||
| spring.servlet.multipart.max-request-size | 1024MB | maximum request size |
|
||||
| server.jetty.max-http-post-size | 5000000 | jetty maximum post size |
|
||||
| spring.banner.charset | UTF-8 | message encoding |
|
||||
| spring.jackson.time-zone | UTC | time zone |
|
||||
| spring.jackson.date-format | "yyyy-MM-dd HH:mm:ss" | time format |
|
||||
| spring.messages.basename | i18n/messages | i18n config |
|
||||
| security.authentication.type | PASSWORD | authentication type |
|
||||
| security.authentication.ldap.user.admin | read-only-admin | admin user account when you log-in with LDAP |
|
||||
| security.authentication.ldap.urls | ldap://ldap.forumsys.com:389/ | LDAP urls |
|
||||
| security.authentication.ldap.base.dn | dc=example,dc=com | LDAP base dn |
|
||||
| security.authentication.ldap.username | cn=read-only-admin,dc=example,dc=com | LDAP username |
|
||||
| security.authentication.ldap.password | password | LDAP password |
|
||||
| security.authentication.ldap.user.identity-attribute | uid | LDAP user identity attribute |
|
||||
| security.authentication.ldap.user.email-attribute | mail | LDAP user email attribute |
|
||||
| security.authentication.ldap.user.not-exist-action | CREATE | action when ldap user is not exist,default value: CREATE. Optional values include(CREATE,DENY) |
|
||||
| security.authentication.ldap.ssl.enable | false | LDAP ssl switch |
|
||||
| security.authentication.ldap.ssl.trust-store | ldapkeystore.jks | LDAP jks file absolute path |
|
||||
| security.authentication.ldap.ssl.trust-store-password | password | LDAP jks password |
|
||||
| security.authentication.casdoor.user.admin | | admin user account when you log-in with Casdoor |
|
||||
| casdoor.endpoint | | Casdoor server url |
|
||||
| casdoor.client-id | | id in Casdoor |
|
||||
| casdoor.client-secret | | secret in Casdoor |
|
||||
| casdoor.certificate | | certificate in Casdoor |
|
||||
| casdoor.organization-name | | organization name in Casdoor |
|
||||
| casdoor.application-name | | application name in Casdoor |
|
||||
| casdoor.redirect-url | | doplhinscheduler login url |
|
||||
| api.traffic.control.global.switch | false | traffic control global switch |
|
||||
| api.traffic.control.max-global-qps-rate | 300 | global max request number per second |
|
||||
| api.traffic.control.tenant-switch | false | traffic control tenant switch |
|
||||
| api.traffic.control.default-tenant-qps-rate | 10 | default tenant max request number per second |
|
||||
| api.traffic.control.customize-tenant-qps-rate | | customize tenant max request number per second |
|
||||
| Parameters | Default value | Description |
|
||||
|-------------------------------------------------------|-------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------|
|
||||
| server.port | 12345 | api service communication port |
|
||||
| server.servlet.session.timeout | 120m | session timeout |
|
||||
| server.servlet.context-path | /dolphinscheduler/ | request path |
|
||||
| spring.servlet.multipart.max-file-size | 1024MB | maximum file size |
|
||||
| spring.servlet.multipart.max-request-size | 1024MB | maximum request size |
|
||||
| server.jetty.max-http-post-size | 5000000 | jetty maximum post size |
|
||||
| spring.banner.charset | UTF-8 | message encoding |
|
||||
| spring.jackson.time-zone | UTC | time zone |
|
||||
| spring.jackson.date-format | "yyyy-MM-dd HH:mm:ss" | time format |
|
||||
| spring.messages.basename | i18n/messages | i18n config |
|
||||
| security.authentication.type | PASSWORD | authentication type |
|
||||
| security.authentication.ldap.user.admin | read-only-admin | admin user account when you log-in with LDAP using the uid attribute of the user |
|
||||
| security.authentication.ldap.user.admin-filter | (&(ou=scientists)(uniqueMember=uid={0},dc=example,dc=com)) | Alternative to "admin" were admin accounts identified by role with LDAP using the uid attribute of the user |
|
||||
| | (&(sAMAccountName={0})(memberOf=CN=admin,OU=dolphin,DC=example,DC=com)) | Alternative example were role attributes with in the LDAP account (memberOf LDAP setup) |
|
||||
| security.authentication.ldap.urls | ldap://ldap.forumsys.com:389/ | LDAP urls |
|
||||
| security.authentication.ldap.base.dn | dc=example,dc=com | LDAP base dn |
|
||||
| security.authentication.ldap.username | cn=read-only-admin,dc=example,dc=com | LDAP username |
|
||||
| security.authentication.ldap.password | password | LDAP password |
|
||||
| security.authentication.ldap.user.identity-attribute | uid | LDAP user identity attribute |
|
||||
| security.authentication.ldap.user.email-attribute | mail | LDAP user email attribute |
|
||||
| security.authentication.ldap.user.not-exist-action | CREATE | action when ldap user is not exist,default value: CREATE. Optional values include(CREATE,DENY) |
|
||||
| security.authentication.ldap.ssl.enable | false | LDAP ssl switch |
|
||||
| security.authentication.ldap.ssl.trust-store | ldapkeystore.jks | LDAP jks file absolute path |
|
||||
| security.authentication.ldap.ssl.trust-store-password | password | LDAP jks password |
|
||||
| security.authentication.casdoor.user.admin | | admin user account when you log-in with Casdoor |
|
||||
| casdoor.endpoint | | Casdoor server url |
|
||||
| casdoor.client-id | | id in Casdoor |
|
||||
| casdoor.client-secret | | secret in Casdoor |
|
||||
| casdoor.certificate | | certificate in Casdoor |
|
||||
| casdoor.organization-name | | organization name in Casdoor |
|
||||
| casdoor.application-name | | application name in Casdoor |
|
||||
| casdoor.redirect-url | | doplhinscheduler login url |
|
||||
| api.traffic.control.global.switch | false | traffic control global switch |
|
||||
| api.traffic.control.max-global-qps-rate | 300 | global max request number per second |
|
||||
| api.traffic.control.tenant-switch | false | traffic control tenant switch |
|
||||
| api.traffic.control.default-tenant-qps-rate | 10 | default tenant max request number per second |
|
||||
| api.traffic.control.customize-tenant-qps-rate | | customize tenant max request number per second |
|
||||
|
||||
### Master Server related configuration
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ package org.apache.dolphinscheduler.api.security.impl.ldap;
|
|||
import org.apache.dolphinscheduler.api.security.impl.AbstractAuthenticator;
|
||||
import org.apache.dolphinscheduler.dao.entity.User;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import lombok.NonNull;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
|
@ -32,12 +34,13 @@ public class LdapAuthenticator extends AbstractAuthenticator {
|
|||
@Override
|
||||
public User login(@NonNull String userId, String password) {
|
||||
User user = null;
|
||||
String ldapEmail = ldapService.ldapLogin(userId, password);
|
||||
if (ldapEmail != null) {
|
||||
Map<String, String> ldapAttributes = ldapService.ldapLogin(userId, password);
|
||||
if (ldapAttributes != null && ldapAttributes.containsKey(LdapService.ATTRIBUTE_EMAIL)) {
|
||||
// check if user exist
|
||||
user = userService.getUserByUserName(userId);
|
||||
if (user == null && ldapService.createIfUserNotExists()) {
|
||||
user = userService.createUser(ldapService.getUserType(userId), userId, ldapEmail);
|
||||
String ldapEmail = ldapAttributes.get(LdapService.ATTRIBUTE_EMAIL);
|
||||
user = userService.createUser(ldapService.getUserType(ldapAttributes), userId, ldapEmail);
|
||||
}
|
||||
}
|
||||
return user;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ import org.apache.dolphinscheduler.common.enums.UserType;
|
|||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.naming.Context;
|
||||
|
|
@ -46,6 +48,9 @@ import org.springframework.stereotype.Component;
|
|||
@Slf4j
|
||||
public class LdapService {
|
||||
|
||||
public static final String ATTRIBUTE_EMAIL = "email";
|
||||
public static final String ATTRIBUTE_USER_TYPE = "userType";
|
||||
|
||||
@Value("${security.authentication.ldap.user.admin:#{null}}")
|
||||
private String adminUserId;
|
||||
|
||||
|
|
@ -67,6 +72,9 @@ public class LdapService {
|
|||
@Value("${security.authentication.ldap.user.email-attribute:#{null}}")
|
||||
private String ldapEmailAttribute;
|
||||
|
||||
@Value("${security.authentication.ldap.user.admin-filter:#{null}}")
|
||||
private String ldapAdminUserFilter;
|
||||
|
||||
@Value("${security.authentication.ldap.user.not-exist-action:CREATE}")
|
||||
private String ldapUserNotExistAction;
|
||||
|
||||
|
|
@ -81,11 +89,18 @@ public class LdapService {
|
|||
|
||||
/***
|
||||
* get user type by configured admin userId
|
||||
* @param userId login userId
|
||||
* @param ldapAttributes login userI ldap attributes (i.e. userId, email, etc...)
|
||||
* @return user type
|
||||
*/
|
||||
public UserType getUserType(String userId) {
|
||||
return adminUserId.equalsIgnoreCase(userId) ? UserType.ADMIN_USER : UserType.GENERAL_USER;
|
||||
public UserType getUserType(Map<String, String> ldapAttributes) {
|
||||
|
||||
if (ldapAttributes.containsKey(ATTRIBUTE_USER_TYPE)) {
|
||||
String userType = ldapAttributes.get(ATTRIBUTE_USER_TYPE);
|
||||
|
||||
return UserType.valueOf(userType);
|
||||
}
|
||||
|
||||
return UserType.GENERAL_USER;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -95,9 +110,11 @@ public class LdapService {
|
|||
* @param userPwd user login password
|
||||
* @return user email
|
||||
*/
|
||||
public String ldapLogin(String userId, String userPwd) {
|
||||
public Map<String, String> ldapLogin(String userId, String userPwd) {
|
||||
Map<String, String> ldapAttributeMap = new HashMap<>();
|
||||
Properties searchEnv = getManagerLdapEnv();
|
||||
LdapContext ctx = null;
|
||||
|
||||
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);
|
||||
|
|
@ -106,10 +123,13 @@ public class LdapService {
|
|||
sc.setSearchScope(SearchControls.SUBTREE_SCOPE);
|
||||
EqualsFilter filter = new EqualsFilter(ldapUserIdentifyingAttribute, userId);
|
||||
NamingEnumeration<SearchResult> results = ctx.search(ldapBaseDn, filter.toString(), sc);
|
||||
|
||||
// Get all requested attributes
|
||||
if (results.hasMore()) {
|
||||
// get the users DN (distinguishedName) from the result
|
||||
SearchResult result = results.next();
|
||||
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());
|
||||
|
|
@ -120,12 +140,30 @@ public class LdapService {
|
|||
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();
|
||||
String value = (String) attr.get();
|
||||
|
||||
ldapAttributeMap.put(ATTRIBUTE_EMAIL, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check for admin role
|
||||
UserType userType =
|
||||
userId.equalsIgnoreCase(adminUserId) ? UserType.ADMIN_USER : UserType.GENERAL_USER;
|
||||
|
||||
ldapAttributeMap.put(ATTRIBUTE_USER_TYPE, userType.toString());
|
||||
|
||||
if (ldapAdminUserFilter != null) {
|
||||
results = ctx.search(ldapBaseDn, ldapAdminUserFilter, new Object[]{userId}, sc);
|
||||
|
||||
if (results.hasMore()) {
|
||||
// found the users with or part of the admin context
|
||||
ldapAttributeMap.put(ATTRIBUTE_USER_TYPE, UserType.ADMIN_USER.toString());
|
||||
}
|
||||
}
|
||||
} catch (NamingException e) {
|
||||
log.error("ldap search error", e);
|
||||
return null;
|
||||
|
|
@ -139,7 +177,7 @@ public class LdapService {
|
|||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
return ldapAttributeMap;
|
||||
}
|
||||
|
||||
/***
|
||||
|
|
|
|||
|
|
@ -109,7 +109,8 @@ public class LdapAuthenticatorTest extends AbstractControllerTest {
|
|||
|
||||
@Test
|
||||
public void testAuthenticate() {
|
||||
when(ldapService.ldapLogin(ldapUid, ldapUserPwd)).thenReturn(ldapEmail);
|
||||
Map<String, String> ldapAttributes = Map.of(LdapService.ATTRIBUTE_EMAIL, ldapEmail);
|
||||
when(ldapService.ldapLogin(ldapUid, ldapUserPwd)).thenReturn(ldapAttributes);
|
||||
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
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import org.apache.dolphinscheduler.common.enums.ProfileType;
|
|||
import org.apache.dolphinscheduler.common.enums.UserType;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
|
@ -49,6 +50,7 @@ import org.springframework.test.context.TestPropertySource;
|
|||
"security.authentication.ldap.ssl.enable=false",
|
||||
"security.authentication.ldap.ssl.trust-store=",
|
||||
"security.authentication.ldap.ssl.trust-store-password=",
|
||||
"security.authentication.ldap.user.admin-filter=(&(ou=scientists)(uniqueMember=uid={0},dc=example,dc=com))"
|
||||
})
|
||||
public class LdapServiceTest {
|
||||
|
||||
|
|
@ -68,28 +70,37 @@ public class LdapServiceTest {
|
|||
|
||||
@Test
|
||||
public void getUserType() {
|
||||
UserType userType = ldapService.getUserType("read-only-admin");
|
||||
UserType userType =
|
||||
ldapService.getUserType(Map.of(LdapService.ATTRIBUTE_USER_TYPE, UserType.ADMIN_USER.toString()));
|
||||
Assertions.assertEquals(UserType.ADMIN_USER, userType);
|
||||
|
||||
userType = ldapService.getUserType(Map.of());
|
||||
Assertions.assertEquals(UserType.GENERAL_USER, userType);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ldapLogin() throws NoSuchFieldException, IllegalAccessException {
|
||||
changeSslEnable(false);
|
||||
String email = ldapService.ldapLogin(username, correctPassword);
|
||||
Map<String, String> ldapAttributes = ldapService.ldapLogin(username, correctPassword);
|
||||
String email = ldapAttributes.get(LdapService.ATTRIBUTE_EMAIL);
|
||||
Assertions.assertEquals("tesla@ldap.forumsys.com", email);
|
||||
String userType = ldapAttributes.get(LdapService.ATTRIBUTE_USER_TYPE);
|
||||
Assertions.assertEquals(UserType.ADMIN_USER.toString(), userType);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ldapLoginError() throws NoSuchFieldException, IllegalAccessException {
|
||||
changeSslEnable(false);
|
||||
String email2 = ldapService.ldapLogin(username, "error password");
|
||||
Assertions.assertNull(email2);
|
||||
Map<String, String> ldapAttributes = ldapService.ldapLogin(username, "error password");
|
||||
Assertions.assertNull(ldapAttributes);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ldapLoginSSL() throws NoSuchFieldException, IllegalAccessException {
|
||||
changeSslEnable(true);
|
||||
String email = ldapService.ldapLogin(username, correctPassword);
|
||||
Map<String, String> ldapAttributes = ldapService.ldapLogin(username, correctPassword);
|
||||
String email = ldapAttributes.get(LdapService.ATTRIBUTE_EMAIL);
|
||||
Assertions.assertNull(email);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -105,8 +105,11 @@ security:
|
|||
username: cn=read-only-admin,dc=example,dc=com
|
||||
password: password
|
||||
user:
|
||||
# admin userId when you use LDAP login
|
||||
# admin userId when you use LDAP login. Properties admin are admin-filter are not mutually exclusive
|
||||
# one uses can be identified by userId and the rest using a role based filter
|
||||
admin: read-only-admin
|
||||
# filter admin users by groups. eg, all scientists are admin users
|
||||
# admin-filter: (&(ou=scientists)(uniqueMember=uid={0},dc=example,dc=com))
|
||||
identity-attribute: uid
|
||||
email-attribute: mail
|
||||
# action when ldap user is not exist (supported types: CREATE,DENY)
|
||||
|
|
|
|||
Loading…
Reference in New Issue