Skip to content

Commit a77f184

Browse files
feat(X-Pack): Add LDAP authentication mechanism
1 parent dcceb1e commit a77f184

File tree

11 files changed

+448
-103
lines changed

11 files changed

+448
-103
lines changed
Lines changed: 5 additions & 0 deletions
Loading

frontend/src/assets/svg/logo_ldap.svg

Lines changed: 2 additions & 2 deletions
Loading

frontend/src/i18n/en.json

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -752,7 +752,18 @@
752752
"oidc_settings": "OIDC Settings",
753753
"metadata_url": "Metadata URL",
754754
"realm": "Realm",
755-
"oidc_field_mapping_placeholder": "e.g., {\"account\": \"oidcAccount\", \"name\": \"oidcName\", \"email\": \"email\"}"
755+
"oidc_field_mapping_placeholder": "e.g., {\"account\": \"oidcAccount\", \"name\": \"oidcName\", \"email\": \"email\"}",
756+
"ldap_settings": "LDAP Settings",
757+
"server_address": "Server Address",
758+
"server_address_placeholder": "Example: ldap://ldap.example.com:389",
759+
"bind_dn": "Bind DN",
760+
"bind_dn_placeholder": "Example: cn=admin,dc=example,dc=com",
761+
"bind_pwd": "Bind Password",
762+
"ou": "User OU",
763+
"ou_placeholder": "Example: ou=users,dc=example,dc=com",
764+
"user_filter": "User Filter",
765+
"user_filter_placeholder": "Example: uid",
766+
"ldap_field_mapping_placeholder": "Example: {\"account\": \"ldapAccount\", \"name\": \"ldapName\", \"email\": \"mail\"}"
756767
},
757768
"login": {
758769
"default_login": "Default",

frontend/src/i18n/ko-KR.json

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -752,7 +752,18 @@
752752
"oidc_settings": "OIDC 설정",
753753
"metadata_url": "메타데이터 URL",
754754
"realm": "영역",
755-
"oidc_field_mapping_placeholder": "예: {\"account\": \"oidcAccount\", \"name\": \"oidcName\", \"email\": \"email\"}"
755+
"oidc_field_mapping_placeholder": "예: {\"account\": \"oidcAccount\", \"name\": \"oidcName\", \"email\": \"email\"}",
756+
"ldap_settings": "LDAP 설정",
757+
"server_address": "서버 주소",
758+
"server_address_placeholder": "예: ldap://ldap.example.com:389",
759+
"bind_dn": "바인드 DN",
760+
"bind_dn_placeholder": "예: cn=admin,dc=example,dc=com",
761+
"bind_pwd": "바인드 비밀번호",
762+
"ou": "사용자 OU",
763+
"ou_placeholder": "예: ou=users,dc=example,dc=com",
764+
"user_filter": "사용자 필터",
765+
"user_filter_placeholder": "예: uid",
766+
"ldap_field_mapping_placeholder": "예: {\"account\": \"ldapAccount\", \"name\": \"ldapName\", \"email\": \"mail\"}"
756767
},
757768
"login": {
758769
"default_login": "기본값",

frontend/src/i18n/zh-CN.json

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -752,7 +752,18 @@
752752
"oidc_settings": "OIDC 设置",
753753
"metadata_url": "元数据地址",
754754
"realm": "领域",
755-
"oidc_field_mapping_placeholder": "例如:{'{'}\"account\": \"oidcAccount\", \"name\": \"oidcName\", \"email\": \"email\"{'}'}"
755+
"oidc_field_mapping_placeholder": "例如:{'{'}\"account\": \"oidcAccount\", \"name\": \"oidcName\", \"email\": \"email\"{'}'}",
756+
"ldap_settings": "LDAP 设置",
757+
"server_address": "服务器地址",
758+
"server_address_placeholder": "例如:ldap://ldap.example.com:389",
759+
"bind_dn": "绑定 DN",
760+
"bind_dn_placeholder": "例如:cn=admin,dc=example,dc=com",
761+
"bind_pwd": "绑定密码",
762+
"ou": "用户 OU",
763+
"ou_placeholder": "例如:ou=users,dc=example,dc=com",
764+
"user_filter": "用户过滤器",
765+
"user_filter_placeholder": "例如:uid",
766+
"ldap_field_mapping_placeholder": "例如:{'{'}\"account\": \"ldapAccount\", \"name\": \"ldapName\", \"email\": \"mail\"{'}'}"
756767
},
757768
"login": {
758769
"default_login": "默认",

frontend/src/views/login/index.vue

Lines changed: 40 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -28,42 +28,45 @@
2828
</div>
2929
<div v-else class="welcome" style="height: 0"></div>
3030
<div class="login-form">
31-
<h2 class="title">{{ $t('common.login') }}</h2>
32-
<el-form
33-
ref="loginFormRef"
34-
class="form-content_error"
35-
:model="loginForm"
36-
:rules="rules"
37-
@keyup.enter="submitForm"
38-
>
39-
<el-form-item prop="username">
40-
<el-input
41-
v-model="loginForm.username"
42-
clearable
43-
:placeholder="$t('common.your_account_email_address')"
44-
size="large"
45-
></el-input>
46-
</el-form-item>
47-
<el-form-item prop="password">
48-
<el-input
49-
v-model="loginForm.password"
50-
:placeholder="$t('common.enter_your_password')"
51-
type="password"
52-
show-password
53-
clearable
54-
size="large"
55-
></el-input>
56-
</el-form-item>
57-
<el-form-item>
58-
<el-button type="primary" class="login-btn" @click="submitForm">{{
59-
$t('common.login_')
60-
}}</el-button>
61-
</el-form-item>
62-
</el-form>
31+
<div class="default-login-tabs">
32+
<h2 class="title">{{ $t('common.login') }}</h2>
33+
<el-form
34+
ref="loginFormRef"
35+
class="form-content_error"
36+
:model="loginForm"
37+
:rules="rules"
38+
@keyup.enter="submitForm"
39+
>
40+
<el-form-item prop="username">
41+
<el-input
42+
v-model="loginForm.username"
43+
clearable
44+
:placeholder="$t('common.your_account_email_address')"
45+
size="large"
46+
></el-input>
47+
</el-form-item>
48+
<el-form-item prop="password">
49+
<el-input
50+
v-model="loginForm.password"
51+
:placeholder="$t('common.enter_your_password')"
52+
type="password"
53+
show-password
54+
clearable
55+
size="large"
56+
></el-input>
57+
</el-form-item>
58+
<el-form-item>
59+
<el-button type="primary" class="login-btn" @click="submitForm">{{
60+
$t('common.login_')
61+
}}</el-button>
62+
</el-form-item>
63+
</el-form>
64+
</div>
6365
<Handler
6466
ref="xpackLoginHandler"
6567
v-model:loading="showLoading"
6668
jsname="L2NvbXBvbmVudC9sb2dpbi9IYW5kbGVy"
69+
@switch-tab="switchTab"
6770
/>
6871
</div>
6972
</div>
@@ -93,7 +96,9 @@ const loginForm = ref({
9396
username: '',
9497
password: '',
9598
})
99+
const activeName = ref('simple')
96100
101+
// const isLdap = computed(() => activeName.value == 'ldap')
97102
const bg = computed(() => {
98103
return appearanceStore.getBg || (appearanceStore.isBlue ? loginImage : login_image)
99104
})
@@ -118,6 +123,9 @@ const submitForm = () => {
118123
}
119124
})
120125
}
126+
const switchTab = (name: string) => {
127+
activeName.value = name || 'simple'
128+
}
121129
</script>
122130

123131
<style lang="less" scoped>

frontend/src/views/login/xpack/Handler.vue

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,19 @@
88
:larksuite="loginCategory.larksuite"
99
/>
1010
</div> -->
11+
<LdapLoginForm v-if="isLdap" />
1112
<el-divider v-if="anyEnable" class="de-other-login-divider">{{
1213
t('login.other_login')
1314
}}</el-divider>
1415
<el-form-item v-if="anyEnable" class="other-login-item">
1516
<div class="login-list">
16-
<!-- <QrcodeLdap
17+
<QrcodeLdap
1718
v-if="loginCategory.qrcode || loginCategory.ldap"
1819
ref="qrcodeLdapHandler"
1920
:qrcode="loginCategory.qrcode"
2021
:ldap="loginCategory.ldap"
2122
@status-change="qrStatusChange"
22-
/> -->
23+
/>
2324
<Oidc v-if="loginCategory.oidc" @switch-category="switcherCategory" />
2425
<Oauth2 v-if="loginCategory.oauth2" ref="oauth2Handler" @switch-category="switcherCategory" />
2526
<Cas v-if="loginCategory.cas" @switch-category="switcherCategory" />
@@ -51,8 +52,9 @@
5152

5253
<script lang="ts" setup>
5354
import { ref, onMounted } from 'vue'
54-
/* import QrcodeLdap from './QrcodeLdap.vue'
55-
import Oidc from './Oidc.vue'
55+
import QrcodeLdap from './QrcodeLdap.vue'
56+
import LdapLoginForm from './LdapLoginForm.vue'
57+
/* import Oidc from './Oidc.vue'
5658
import Oauth2 from './Oauth2.vue'
5759
import Saml2 from './Saml2.vue' */
5860
import Oidc from './Oidc.vue'
@@ -70,6 +72,7 @@ import { loadClient, type LoginCategory } from './PlatformClient'
7072
// import { logoutHandler } from '@/utils/logout'
7173
import { useI18n } from 'vue-i18n'
7274
// import PlatformError from './PlatformError.vue'
75+
const isLdap = ref(false)
7376
defineProps<{
7477
loading: boolean
7578
}>()
@@ -211,14 +214,16 @@ const init = (cb?: () => void) => {
211214
})
212215
}
213216
214-
/* const qrStatusChange = (activeComponent: string) => {
217+
const qrStatusChange = (activeComponent: string) => {
215218
qrStatus.value = activeComponent === 'qrcode'
219+
isLdap.value = false
216220
if (activeComponent === 'account') {
217221
emits('switchTab', 'simple')
218222
} else if (activeComponent === 'ldap') {
223+
isLdap.value = true
219224
switcherCategory({ category: 'ldap', proxy: '' })
220225
}
221-
} */
226+
}
222227
/* const showMfa = ref(false)
223228
const toMfa = (mfa) => {
224229
state.mfaData = mfa
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
<template>
2+
<div class="default-login-tabs-ldap">
3+
<h2 class="title">{{ t('login.ldap_login') }}</h2>
4+
<el-form
5+
ref="loginFormRef"
6+
class="form-content_error"
7+
:model="loginForm"
8+
@keyup.enter="submitForm"
9+
>
10+
<el-form-item prop="username">
11+
<el-input
12+
v-model="loginForm.username"
13+
clearable
14+
:placeholder="t('login.input_account')"
15+
size="large"
16+
></el-input>
17+
</el-form-item>
18+
<el-form-item prop="password">
19+
<el-input
20+
v-model="loginForm.password"
21+
:placeholder="$t('common.enter_your_password')"
22+
type="password"
23+
show-password
24+
clearable
25+
size="large"
26+
></el-input>
27+
</el-form-item>
28+
<el-form-item>
29+
<el-button type="primary" class="login-btn" @click="submitForm">{{
30+
$t('common.login_')
31+
}}</el-button>
32+
</el-form-item>
33+
</el-form>
34+
</div>
35+
</template>
36+
37+
<script setup lang="ts">
38+
import { ref } from 'vue'
39+
import { useI18n } from 'vue-i18n'
40+
import { request } from '@/utils/request'
41+
import { useRouter } from 'vue-router'
42+
import { useUserStore } from '@/stores/user.ts'
43+
44+
const userStore = useUserStore()
45+
const router = useRouter()
46+
const { t } = useI18n()
47+
const loginForm = ref({
48+
username: '',
49+
password: '',
50+
origin: 1,
51+
})
52+
const loginFormRef = ref()
53+
const submitForm = () => {
54+
loginFormRef.value.validate((valid: boolean) => {
55+
if (valid) {
56+
const data = { ...loginForm.value }
57+
request.post('/system/authentication/sso/3', data).then((res: any) => {
58+
const token = res.access_token
59+
userStore.setToken(token)
60+
userStore.setExp(res.exp)
61+
userStore.setTime(Date.now())
62+
router.push('/')
63+
})
64+
}
65+
})
66+
}
67+
</script>
68+
69+
<style lang="less" scoped>
70+
.form-content_error {
71+
.ed-form-item--default {
72+
margin-bottom: 24px;
73+
&.is-error {
74+
margin-bottom: 48px;
75+
}
76+
}
77+
}
78+
79+
.title {
80+
font-weight: 500;
81+
font-style: Medium;
82+
font-size: 20px;
83+
line-height: 28px;
84+
margin-bottom: 24px;
85+
}
86+
87+
.login-btn {
88+
width: 100%;
89+
height: 45px;
90+
font-size: 16px;
91+
border-radius: 4px;
92+
}
93+
94+
.agreement {
95+
margin-top: 20px;
96+
text-align: center;
97+
color: #666;
98+
}
99+
</style>

0 commit comments

Comments
 (0)