From bd0d7a9cdc8e0bb2b93f2c6a50acb65201e92487 Mon Sep 17 00:00:00 2001 From: fit2cloud-chenyw Date: Thu, 18 Jul 2024 14:53:46 +0800 Subject: [PATCH] =?UTF-8?q?feat(X-Pack):=20=E6=96=B0=E5=A2=9ELDAP=E8=AE=A4?= =?UTF-8?q?=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core-frontend/src/config/axios/service.ts | 2 - core/core-frontend/src/views/login/index.vue | 37 ++++++++++++------- de-xpack | 2 +- .../settings/XpackAuthenticationApi.java | 14 +++++-- .../api/xpack/settings/vo/XpackLdapVO.java | 25 +++++++++++++ sdk/api/api-permissions/pom.xml | 7 ++++ .../permissions/login/dto/PwdLoginDTO.java | 4 ++ .../main/java/io/dataease/utils/AesUtils.java | 29 +++++++++++++++ 8 files changed, 100 insertions(+), 20 deletions(-) create mode 100644 sdk/api/api-base/src/main/java/io/dataease/api/xpack/settings/vo/XpackLdapVO.java diff --git a/core/core-frontend/src/config/axios/service.ts b/core/core-frontend/src/config/axios/service.ts index 1f710c179c..320c7b93bb 100644 --- a/core/core-frontend/src/config/axios/service.ts +++ b/core/core-frontend/src/config/axios/service.ts @@ -111,8 +111,6 @@ service.interceptors.request.use( ;(config.headers as AxiosRequestHeaders)['X-DE-LINK-TOKEN'] = linkStore.getLinkToken } else if (embeddedStore.token) { ;(config.headers as AxiosRequestHeaders)['X-EMBEDDED-TOKEN'] = embeddedStore.token - } else if (wsCache.get('de-ldap-token')) { - ;(config.headers as AxiosRequestHeaders)['Authorization'] = wsCache.get('de-ldap-token') } if (wsCache.get('user.language')) { const key = wsCache.get('user.language') diff --git a/core/core-frontend/src/views/login/index.vue b/core/core-frontend/src/views/login/index.vue index 0e2af9b670..39cfbd7e0a 100644 --- a/core/core-frontend/src/views/login/index.vue +++ b/core/core-frontend/src/views/login/index.vue @@ -141,10 +141,14 @@ const ldapValidate = callback => { if (!formRef.value) return formRef.value.validate((valid: boolean) => { if (valid && callback) { + duringLogin.value = true callback() } }) } +const ldapFeedback = () => { + duringLogin.value = false +} const activeType = ref('account') const tablePaneList = ref([{ title: '普通登录', name: 'simple' }]) const xpackLoaded = info => { @@ -230,23 +234,28 @@ onMounted(async () => { if (!checkPlatform()) { const res = await loginCategoryApi() const adminLogin = router.currentRoute?.value?.name === 'admin-login' - if (adminLogin && !res.data) { + if (adminLogin && (!res.data || res.data === 1)) { router.push('/401') return } if (res.data && !adminLogin) { - loadingText.value = '加载中...' - document.getElementsByClassName('ed-loading-text')?.length && - (document.getElementsByClassName('ed-loading-text')[0]['innerText'] = loadingText.value) - nextTick(() => { - const param = { methodName: 'ssoLogin', args: res.data } - const timer = setInterval(() => { - if (xpackLoginHandler?.value.invokeMethod) { - xpackLoginHandler?.value.invokeMethod(param) - clearInterval(timer) - } - }, 1000) - }) + if (res.data === 1) { + activeName.value = 'LDAP' + preheat.value = false + } else { + loadingText.value = '加载中...' + document.getElementsByClassName('ed-loading-text')?.length && + (document.getElementsByClassName('ed-loading-text')[0]['innerText'] = loadingText.value) + nextTick(() => { + const param = { methodName: 'ssoLogin', args: res.data } + const timer = setInterval(() => { + if (xpackLoginHandler?.value.invokeMethod) { + xpackLoginHandler?.value.invokeMethod(param) + clearInterval(timer) + } + }, 1000) + }) + } } else { preheat.value = false } @@ -325,7 +334,9 @@ onMounted(async () => { diff --git a/de-xpack b/de-xpack index e7fbd2e199..d1d457a0c6 160000 --- a/de-xpack +++ b/de-xpack @@ -1 +1 @@ -Subproject commit e7fbd2e19945f1d35578b2e8e824bd605a49c8f6 +Subproject commit d1d457a0c68f1f8c01b25e6533953b870ebe793a diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/xpack/settings/XpackAuthenticationApi.java b/sdk/api/api-base/src/main/java/io/dataease/api/xpack/settings/XpackAuthenticationApi.java index 393f7691e9..0fd39d16cc 100644 --- a/sdk/api/api-base/src/main/java/io/dataease/api/xpack/settings/XpackAuthenticationApi.java +++ b/sdk/api/api-base/src/main/java/io/dataease/api/xpack/settings/XpackAuthenticationApi.java @@ -2,10 +2,7 @@ package io.dataease.api.xpack.settings; import com.github.xiaoymin.knife4j.annotations.ApiSupport; import io.dataease.api.xpack.settings.request.XpackAuthenticationEditor; -import io.dataease.api.xpack.settings.vo.XpackCasVO; -import io.dataease.api.xpack.settings.vo.XpackOidcVO; -import io.dataease.api.xpack.settings.vo.XpackAuthenticationStatusVO; -import io.dataease.api.xpack.settings.vo.XpackAuthenticationVO; +import io.dataease.api.xpack.settings.vo.*; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.web.bind.annotation.GetMapping; @@ -34,6 +31,9 @@ public interface XpackAuthenticationApi { @PostMapping("/save/cas") String saveCas(@RequestBody XpackCasVO editor); + @PostMapping("/save/ldap") + String saveLdap(@RequestBody XpackLdapVO editor); + @GetMapping("/info/oidc") XpackOidcVO oidcInfo(); @@ -41,6 +41,9 @@ public interface XpackAuthenticationApi { @GetMapping("/info/cas") XpackCasVO casInfo(); + @GetMapping("/info/ldap") + XpackLdapVO ldapInfo(); + @PostMapping("/validate/oidc") String validateOidc(@RequestBody XpackOidcVO editor); @@ -48,6 +51,9 @@ public interface XpackAuthenticationApi { @PostMapping("/validate/cas") String validateCas(@RequestBody XpackCasVO editor); + @PostMapping("/validate/ldap") + String validateLdap(@RequestBody XpackLdapVO editor); + @PostMapping("/validateId/{id}") String validate(@PathVariable("id") Long id); diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/xpack/settings/vo/XpackLdapVO.java b/sdk/api/api-base/src/main/java/io/dataease/api/xpack/settings/vo/XpackLdapVO.java new file mode 100644 index 0000000000..e60f04544a --- /dev/null +++ b/sdk/api/api-base/src/main/java/io/dataease/api/xpack/settings/vo/XpackLdapVO.java @@ -0,0 +1,25 @@ +package io.dataease.api.xpack.settings.vo; + +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +@Data +public class XpackLdapVO implements Serializable { + @Serial + private static final long serialVersionUID = -2996803523472015035L; + + private String addr; + + private String dn; + + private String pwd; + + private String ou; + + private String filter; + + private String mapping; + +} diff --git a/sdk/api/api-permissions/pom.xml b/sdk/api/api-permissions/pom.xml index b99e29ab5a..c233ac60b8 100644 --- a/sdk/api/api-permissions/pom.xml +++ b/sdk/api/api-permissions/pom.xml @@ -11,4 +11,11 @@ api-permissions + + + org.springframework.boot + spring-boot-starter-data-ldap + + + \ No newline at end of file diff --git a/sdk/api/api-permissions/src/main/java/io/dataease/api/permissions/login/dto/PwdLoginDTO.java b/sdk/api/api-permissions/src/main/java/io/dataease/api/permissions/login/dto/PwdLoginDTO.java index cc80614d61..49ec7e03b5 100644 --- a/sdk/api/api-permissions/src/main/java/io/dataease/api/permissions/login/dto/PwdLoginDTO.java +++ b/sdk/api/api-permissions/src/main/java/io/dataease/api/permissions/login/dto/PwdLoginDTO.java @@ -1,5 +1,6 @@ package io.dataease.api.permissions.login.dto; +import io.swagger.v3.oas.annotations.Hidden; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; import lombok.Data; @@ -15,4 +16,7 @@ public class PwdLoginDTO { @Schema(description = "密码(需加密)", requiredMode = Schema.RequiredMode.REQUIRED) @NotBlank(message = "login.validator.pwd") private String pwd; + @Hidden + private Integer origin = 0; + } diff --git a/sdk/common/src/main/java/io/dataease/utils/AesUtils.java b/sdk/common/src/main/java/io/dataease/utils/AesUtils.java index 1dec907316..ed7d454ed5 100644 --- a/sdk/common/src/main/java/io/dataease/utils/AesUtils.java +++ b/sdk/common/src/main/java/io/dataease/utils/AesUtils.java @@ -33,4 +33,33 @@ public class AesUtils { throw new RuntimeException("decrypt error,please check parameters", e); } } + + public static String aesEncrypt(String src, String secretKey, String iv) { + if (StringUtils.isBlank(secretKey)) { + throw new RuntimeException("secretKey is empty"); + } + + try { + byte[] raw = secretKey.getBytes(UTF_8); + SecretKeySpec secretKeySpec = new SecretKeySpec(raw, "AES"); + // "算法/模式/补码方式" ECB + Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); + IvParameterSpec iv1 = new IvParameterSpec(iv.getBytes()); + cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, iv1); + byte[] encrypted = cipher.doFinal(src.getBytes(UTF_8)); + return Base64.encodeBase64String(encrypted); + } catch (Exception e) { + throw new RuntimeException("AES encrypt error:", e); + } + + } + + public static Object aesEncrypt(Object o) { + + return o == null ? null : aesEncrypt(o.toString(), "www.fit2cloud.co", "1234567890123456"); + } + + public static Object aesDecrypt(Object o) { + return o == null ? null : aesDecrypt(o.toString(), "www.fit2cloud.co", "1234567890123456"); + } }