Skip to content

feat: 支持cas和oidc认证 #955

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ui/src/api/auth-setting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const prefix = '/auth'
* 获取认证设置
*/
const getAuthSetting: (auth_type: string, loading?: Ref<boolean>) => Promise<Result<any>> = (auth_type, loading) => {
return get(`${prefix}/${auth_type}/info`, undefined, loading)
return get(`${prefix}/${auth_type}/detail`, undefined, loading)
}

/**
Expand Down
34 changes: 32 additions & 2 deletions ui/src/locales/lang/en_US/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,36 @@ export default {
testConnectionSuccess: 'Test Connection Success',
testConnectionFailed: 'Test Connection Failed',
saveSuccess: 'Save Success',
}
}
},
cas: {
title: 'CAS Settings',
ldpUri: 'ldpUri',
ldpUriPlaceholder: 'Please enter ldpUri',
redirectUrl: 'Callback Address',
redirectUrlPlaceholder: 'Please enter Callback Address',
enableAuthentication: 'Enable CAS Authentication',
saveSuccess: 'Save Success',
save: 'Save',
},
oidc: {
title: 'OIDC Settings',
authEndpoint: 'Auth Endpoint',
authEndpointPlaceholder: 'Please enter Auth Endpoint',
tokenEndpoint: 'Token Endpoint',
tokenEndpointPlaceholder: 'Please enter Token Endpoint',
userInfoEndpoint: 'User Info Endpoint',
userInfoEndpointPlaceholder: 'Please enter User Info Endpoint',
clientId: 'Client ID',
clientIdPlaceholder: 'Please enter Client ID',
clientSecret: 'Client Secret',
clientSecretPlaceholder: 'Please enter Client Secret',
logoutEndpoint: 'Logout Endpoint',
logoutEndpointPlaceholder: 'Please enter Logout Endpoint',
redirectUrl: 'Redirect URL',
redirectUrlPlaceholder: 'Please enter Redirect URL',
enableAuthentication: 'Enable OIDC Authentication',
},
jump_tip: 'Jumping to the authentication source page for authentication',
jump: 'Jump',
},
};
50 changes: 40 additions & 10 deletions ui/src/locales/lang/zh_CN/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,55 @@ export default {
login: {
authentication: '登录认证',
ldap: {
title: 'LDAP设置',
address: 'LDAP地址',
serverPlaceholder: '请输入LDAP地址',
title: 'LDAP 设置',
address: 'LDAP 地址',
serverPlaceholder: '请输入LDAP 地址',
bindDN: '绑定DN',
bindDNPlaceholder: '请输入绑定DN',
bindDNPlaceholder: '请输入绑定 DN',
password: '密码',
passwordPlaceholder: '请输入密码',
ou: '用户OU',
ouPlaceholder: '请输入用户OU',
ouPlaceholder: '请输入用户 OU',
ldap_filter: '用户过滤器',
ldap_filterPlaceholder: '请输入用户过滤器',
ldap_mapping: 'LDAP属性映射',
ldap_mappingPlaceholder: '请输入LDAP属性映射',
ldap_mapping: 'LDAP 属性映射',
ldap_mappingPlaceholder: '请输入 LDAP 属性映射',
test: '测试连接',
enableAuthentication: '启用LDAP认证',
enableAuthentication: '启用 LDAP 认证',
save: '保存',
testConnectionSuccess: '测试连接成功',
testConnectionFailed: '测试连接失败',
saveSuccess: '保存成功',
}
}
},
cas: {
title: 'CAS 设置',
ldpUri: 'ldpUri',
ldpUriPlaceholder: '请输入ldpUri',
redirectUrl: '回调地址',
redirectUrlPlaceholder: '请输入回调地址',
enableAuthentication: '启用CAS认证',
saveSuccess: '保存成功',
save: '保存',
},
oidc: {
title: 'OIDC 设置',
authEndpoint: '授权端地址',
authEndpointPlaceholder: '请输入授权端地址',
tokenEndpoint: 'Token端地址',
tokenEndpointPlaceholder: '请输入Token端地址',
userInfoEndpoint: '用户信息端地址',
userInfoEndpointPlaceholder: '请输入用户信息端地址',
clientId: '客户端ID',
clientIdPlaceholder: '请输入客户端ID',
clientSecret: '客户端密钥',
clientSecretPlaceholder: '请输入客户端密钥',
logoutEndpoint: '注销端地址',
logoutEndpointPlaceholder: '请输入注销端地址',
redirectUrl: '回调地址',
redirectUrlPlaceholder: '请输入回调地址',
enableAuthentication: '启用OIDC认证',
},
jump_tip: '即将跳转至认证源页面进行认证',
jump: '跳转',
},
};
3 changes: 3 additions & 0 deletions ui/src/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ router.beforeEach(
const notAuthRouteNameList = ['register', 'login', 'forgot_password', 'reset_password', 'Chat']

if (!notAuthRouteNameList.includes(to.name ? to.name.toString() : '')) {
if (to.query && to.query.token) {
localStorage.setItem('token', to.query.token.toString())
}
const token = user.getToken()
if (!token) {
next({
Expand Down
4 changes: 4 additions & 0 deletions ui/src/views/application/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -189,8 +189,12 @@ function getList() {
}

onMounted(() => {
console.log(router)
getList()
})



</script>
<style lang="scss" scoped>
.application-card {
Expand Down
86 changes: 86 additions & 0 deletions ui/src/views/authentication/component/CAS.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<template>
<div class="p-24" v-loading="loading">
<el-form
ref="authFormRef"
:rules="rules"
:model="form"
label-position="top"
require-asterisk-position="right"
>
<el-form-item :label="$t('login.cas.ldpUri')" prop="config_data.ldpUri">
<el-input v-model="form.config_data.ldpUri" :placeholder="$t('login.cas.ldpUriPlaceholder')"/>
</el-form-item>
<el-form-item :label="$t('login.cas.redirectUrl')" prop="config_data.redirectUrl">
<el-input v-model="form.config_data.redirectUrl" :placeholder="$t('login.cas.redirectUrlPlaceholder')"/>
</el-form-item>
<el-form-item>
<el-checkbox v-model="form.is_active">{{ $t('login.cas.enableAuthentication') }}</el-checkbox>
</el-form-item>
</el-form>

<div class="text-right">
<el-button @click="submit(authFormRef)" type="primary" :disabled="loading"> {{ $t('login.cas.save') }}
</el-button>
</div>
</div>
</template>
<script setup lang="ts">
import {reactive, ref, watch, onMounted} from 'vue'
import authApi from '@/api/auth-setting'
import type {FormInstance, FormRules} from 'element-plus'
import {t} from '@/locales'
import {MsgSuccess} from '@/utils/message'

const form = ref<any>({
id: '',
auth_type: 'CAS',
config_data: {
ldpUri: '',
redirectUrl: '',
},
is_active: true
})

const authFormRef = ref()

const loading = ref(false)

const rules = reactive<FormRules<any>>({
'config_data.ldpUri': [{required: true, message: t('login.ldap.ldpUriPlaceholder'), trigger: 'blur'}],
'config_data.redirectUrl': [{
required: true,
message: t('login.ldap.redirectUrlPlaceholder'),
trigger: 'blur'
}],
})

const submit = async (formEl: FormInstance | undefined, test?: string) => {
if (!formEl) return
await formEl.validate((valid, fields) => {
if (valid) {
if (test) {
authApi.postAuthSetting(form.value, loading).then((res) => {
MsgSuccess(t('login.cas.testConnectionSuccess'))
})
} else {
authApi.putAuthSetting(form.value.auth_type, form.value, loading).then((res) => {
MsgSuccess(t('login.cas.saveSuccess'))
})
}
}
})
}

function getDetail() {
authApi.getAuthSetting(form.value.auth_type, loading).then((res: any) => {
if (res.data && JSON.stringify(res.data) !== '{}') {
form.value = res.data
}
})
}

onMounted(() => {
getDetail()
})
</script>
<style lang="scss" scoped></style>
112 changes: 112 additions & 0 deletions ui/src/views/authentication/component/OIDC.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
<template>
<div class="p-24" v-loading="loading">
<el-form
ref="authFormRef"
:rules="rules"
:model="form"
label-position="top"
require-asterisk-position="right"
>
<el-form-item :label="$t('login.oidc.authEndpoint')" prop="config_data.authEndpoint">
<el-input v-model="form.config_data.authEndpoint" :placeholder="$t('login.oidc.authEndpointPlaceholder')"/>
</el-form-item>
<el-form-item :label="$t('login.oidc.tokenEndpoint')" prop="config_data.tokenEndpoint">
<el-input v-model="form.config_data.tokenEndpoint" :placeholder="$t('login.oidc.tokenEndpointPlaceholder')"/>
</el-form-item>
<el-form-item :label="$t('login.oidc.userInfoEndpoint')" prop="config_data.userInfoEndpoint">
<el-input v-model="form.config_data.userInfoEndpoint"
:placeholder="$t('login.oidc.userInfoEndpointPlaceholder')"/>
</el-form-item>
<el-form-item :label="$t('login.oidc.clientId')" prop="config_data.clientId">
<el-input v-model="form.config_data.clientId" :placeholder="$t('login.oidc.clientIdPlaceholder')"/>
</el-form-item>
<el-form-item :label="$t('login.oidc.clientSecret')" prop="config_data.clientSecret">
<el-input v-model="form.config_data.clientSecret" :placeholder="$t('login.oidc.clientSecretPlaceholder')"
show-password/>
</el-form-item>
<el-form-item :label="$t('login.oidc.redirectUrl')" prop="config_data.redirectUrl">
<el-input v-model="form.config_data.redirectUrl" :placeholder="$t('login.oidc.redirectUrlPlaceholder')"/>
</el-form-item>
<el-form-item>
<el-checkbox v-model="form.is_active">{{ $t('login.oidc.enableAuthentication') }}</el-checkbox>
</el-form-item>
</el-form>

<div class="text-right">
<el-button @click="submit(authFormRef)" type="primary" :disabled="loading"> {{ $t('login.ldap.save') }}
</el-button>
</div>
</div>
</template>
<script setup lang="ts">
import {reactive, ref, watch, onMounted} from 'vue'
import authApi from '@/api/auth-setting'
import type {FormInstance, FormRules} from 'element-plus'
import {t} from '@/locales'
import {MsgSuccess} from '@/utils/message'

const form = ref<any>({
id: '',
auth_type: 'OIDC',
config_data: {
authEndpoint: '',
tokenEndpoint: '',
userInfoEndpoint: '',
clientId: '',
clientSecret: '',
redirectUrl: ''
},
is_active: true
})

const authFormRef = ref()

const loading = ref(false)

const rules = reactive<FormRules<any>>({
'config_data.authEndpoint': [{required: true, message: t('login.oidc.authEndpointPlaceholder'), trigger: 'blur'}],
'config_data.tokenEndpoint': [{required: true, message: t('login.oidc.tokenEndpointPlaceholder'), trigger: 'blur'}],
'config_data.userInfoEndpoint': [{
required: true,
message: t('login.oidc.userInfoEndpointPlaceholder'),
trigger: 'blur'
}],
'config_data.clientId': [{required: true, message: t('login.oidc.clientIdPlaceholder'), trigger: 'blur'}],
'config_data.clientSecret': [{required: true, message: t('login.oidc.clientSecretPlaceholder'), trigger: 'blur'}],
'config_data.redirectUrl': [{required: true, message: t('login.oidc.redirectUrlPlaceholder'), trigger: 'blur'}],
'config_data.logoutEndpoint': [{required: true, message: t('login.oidc.logoutEndpointPlaceholder'), trigger: 'blur'}]
})

const submit = async (formEl: FormInstance | undefined, test?: string) => {
if (!formEl) return
await formEl.validate((valid, fields) => {
if (valid) {
if (test) {
authApi.postAuthSetting(form.value, loading).then((res) => {
MsgSuccess(t('login.ldap.testConnectionSuccess'))
})
} else {
authApi.putAuthSetting(form.value.auth_type, form.value, loading).then((res) => {
MsgSuccess(t('login.ldap.saveSuccess'))
})
}
}
})
}

function getDetail() {
authApi.getAuthSetting(form.value.auth_type, loading).then((res: any) => {
if (res.data && JSON.stringify(res.data) !== '{}') {
form.value = res.data
if (res.data.config_data.ldap_mapping) {
form.value.config_data.ldap_mapping = JSON.stringify(JSON.parse(res.data.config_data.ldap_mapping))
}
}
})
}

onMounted(() => {
getDetail()
})
</script>
<style lang="scss" scoped></style>
12 changes: 12 additions & 0 deletions ui/src/views/authentication/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import { ref, computed, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import LDAP from './component/LDAP.vue'
import CAS from './component/CAS.vue'
import OIDC from './component/OIDC.vue'
import { t } from '@/locales'
import useStore from '@/stores'

Expand All @@ -32,6 +34,16 @@ const tabList = [
label: t('login.ldap.title'),
name: 'LDAP',
component: LDAP
},
{
label: t('login.cas.title'),
name: 'CAS',
component: CAS
},
{
label: t('login.oidc.title'),
name: 'OIDC',
component: OIDC
}
]

Expand Down
Loading
Loading