Commit a7dbf2155f7af2255e1bb69b0770cc694be60c83
1 parent
f6f3c5c4
系统认证相关代码提交
Signed-off-by: TanYibin <5491541@qq.com>
Showing
15 changed files
with
765 additions
and
66 deletions
.gitignore
ant-design-vue-jeecg/src/config/router.config.js
... | ... | @@ -320,6 +320,11 @@ export const constantRouterMap = [ |
320 | 320 | name: 'alteration', |
321 | 321 | component: () => import(/* webpackChunkName: "user" */ '@/views/user/alteration/Alteration') |
322 | 322 | }, |
323 | + { | |
324 | + path: 'systemTokenModal', | |
325 | + name: 'systemTokenModal', | |
326 | + component: () => import(/* webpackChunkName: "user" */ '@/views/user/modules/SystemTokenModal') | |
327 | + }, | |
323 | 328 | ] |
324 | 329 | }, |
325 | 330 | |
... | ... |
ant-design-vue-jeecg/src/permission.js
... | ... | @@ -9,7 +9,7 @@ import {generateIndexRouter, isOAuth2AppEnv} from '@/utils/util' |
9 | 9 | |
10 | 10 | NProgress.configure({showSpinner: false}) // NProgress Configuration |
11 | 11 | |
12 | -const whiteList = ['/user/login', '/user/register', '/user/register-result', '/user/alteration'] // no redirect whitelist | |
12 | +const whiteList = ['/user/login', '/user/register', '/user/register-result', '/user/alteration','/user/systemTokenModal'] // no redirect whitelist | |
13 | 13 | whiteList.push(OAUTH2_LOGIN_PAGE_PATH) |
14 | 14 | |
15 | 15 | router.beforeEach((to, from, next) => { |
... | ... |
ant-design-vue-jeecg/src/views/user/Login.vue
1 | 1 | <template> |
2 | 2 | <div class="main"> |
3 | 3 | <a-form-model class="user-layout-login" @keyup.enter.native="handleSubmit"> |
4 | - <a-tabs :activeKey="customActiveKey" :tabBarStyle="{ textAlign: 'center', borderBottom: 'unset' }" | |
5 | - @change="handleTabClick"> | |
4 | + <a-tabs :activeKey="customActiveKey" :tabBarStyle="{ textAlign: 'center', borderBottom: 'unset' }" @change="handleTabClick"> | |
6 | 5 | <a-tab-pane key="tab1" tab="账号密码登录"> |
7 | - <login-account ref="alogin" @validateFail="validateFail" @success="requestSuccess" | |
8 | - @fail="requestFailed"></login-account> | |
6 | + <login-account ref="alogin" @validateFail="validateFail" @success="requestSuccess" @fail="requestFailed"></login-account> | |
9 | 7 | </a-tab-pane> |
10 | - | |
11 | 8 | <!-- <a-tab-pane key="tab2" tab="手机号登录">--> |
12 | 9 | <!-- <login-phone ref="plogin" @validateFail="validateFail" @success="requestSuccess" @fail="requestFailed"></login-phone>--> |
13 | 10 | <!-- </a-tab-pane>--> |
14 | 11 | </a-tabs> |
15 | - | |
16 | 12 | <!-- <a-form-model-item>--> |
17 | 13 | <!-- <a-checkbox @change="handleRememberMeChange" default-checked>自动登录</a-checkbox>--> |
18 | 14 | <!-- <router-link :to="{ name: 'alteration'}" class="forge-password" style="float: right;">--> |
... | ... | @@ -22,23 +18,18 @@ |
22 | 18 | <!-- 注册账户--> |
23 | 19 | <!-- </router-link>--> |
24 | 20 | <!-- </a-form-model-item>--> |
25 | - | |
26 | - | |
27 | 21 | <a-form-item style="margin-top:24px"> |
28 | - <a-button size="large" type="primary" htmlType="submit" class="login-button" :loading="loginBtn" | |
29 | - @click.stop.prevent="handleSubmit" :disabled="loginBtn">确定 | |
22 | + <a-button size="large" type="primary" htmlType="submit" class="login-button" :loading="loginBtn" @click.stop.prevent="handleSubmit" :disabled="loginBtn">确定 | |
30 | 23 | </a-button> |
31 | 24 | </a-form-item> |
32 | - | |
33 | 25 | </a-form-model> |
34 | - | |
35 | - <two-step-captcha v-if="requiredTwoStepCaptcha" :visible="stepCaptchaVisible" @success="stepCaptchaSuccess" | |
36 | - @cancel="stepCaptchaCancel"></two-step-captcha> | |
26 | + <two-step-captcha v-if="requiredTwoStepCaptcha" :visible="stepCaptchaVisible" @success="stepCaptchaSuccess" @cancel="stepCaptchaCancel"></two-step-captcha> | |
37 | 27 | <login-select-tenant ref="loginSelect" @success="loginSelectOk"></login-select-tenant> |
38 | 28 | <!-- <third-login ref="thirdLogin"></third-login>--> |
39 | 29 | </div> |
40 | 30 | </template> |
41 | 31 | |
32 | + | |
42 | 33 | <script> |
43 | 34 | import Vue from 'vue' |
44 | 35 | import {ACCESS_TOKEN, ENCRYPTED_STRING} from '@/store/mutation-types' |
... | ... | @@ -47,7 +38,6 @@ import LoginSelectTenant from './LoginSelectTenant' |
47 | 38 | import TwoStepCaptcha from '@/components/tools/TwoStepCaptcha' |
48 | 39 | import {getEncryptedString} from '@/utils/encryption/aesEncrypt' |
49 | 40 | import {timeFix} from '@/utils/util' |
50 | - | |
51 | 41 | import LoginAccount from './LoginAccount' |
52 | 42 | import LoginPhone from './LoginPhone' |
53 | 43 | |
... | ... | @@ -94,8 +84,6 @@ export default { |
94 | 84 | } |
95 | 85 | }) |
96 | 86 | }, |
97 | - | |
98 | - | |
99 | 87 | //登录 |
100 | 88 | handleSubmit() { |
101 | 89 | this.loginBtn = true; |
... | ... | @@ -134,15 +122,12 @@ export default { |
134 | 122 | }, |
135 | 123 | //登录成功 |
136 | 124 | loginSuccess() { |
137 | - this.$router.push({path: "/dashboard/analysis"}).catch(() => { | |
138 | - console.log('登录跳转首页出错,这个错误从哪里来的') | |
139 | - }) | |
125 | + this.$router.push({path: "/dashboard/analysis"}); | |
140 | 126 | this.$notification.success({ |
141 | 127 | message: '欢迎', |
142 | 128 | description: `${timeFix()},欢迎回来`, |
143 | 129 | }); |
144 | 130 | }, |
145 | - | |
146 | 131 | stepCaptchaSuccess() { |
147 | 132 | this.loginSuccess() |
148 | 133 | }, |
... | ... | @@ -163,9 +148,7 @@ export default { |
163 | 148 | this.encryptedString = encryptedString; |
164 | 149 | } |
165 | 150 | } |
166 | - | |
167 | 151 | } |
168 | - | |
169 | 152 | } |
170 | 153 | </script> |
171 | 154 | <style lang="less" scoped> |
... | ... | @@ -213,10 +196,9 @@ export default { |
213 | 196 | float: right; |
214 | 197 | } |
215 | 198 | } |
216 | -} | |
217 | -</style> | |
218 | -<style> | |
219 | -.valid-error .ant-select-selection__placeholder { | |
220 | - color: #f5222d; | |
199 | + | |
200 | + .valid-error .ant-select-selection__placeholder { | |
201 | + color: #f5222d; | |
202 | + } | |
221 | 203 | } |
222 | 204 | </style> |
223 | 205 | \ No newline at end of file |
... | ... |
ant-design-vue-jeecg/src/views/user/LoginAccount.vue
... | ... | @@ -31,8 +31,9 @@ |
31 | 31 | </template> |
32 | 32 | |
33 | 33 | <script> |
34 | -import {getAction} from '@/api/manage' | |
35 | 34 | import Vue from 'vue' |
35 | +import {getAction} from '@/api/manage' | |
36 | +import SystemTokenModal from './modules/SystemTokenModal' | |
36 | 37 | import {mapActions} from 'vuex' |
37 | 38 | import {getWarehouseByUserCode} from '@/api/api' |
38 | 39 | |
... | ... | @@ -140,7 +141,7 @@ export default { |
140 | 141 | acceptUsername(username) { |
141 | 142 | this.model['username'] = username |
142 | 143 | }, |
143 | - //账号密码登录 | |
144 | + // 账号密码登录 | |
144 | 145 | handleLogin(rememberMe) { |
145 | 146 | this.validateFields(['username', 'password'], (err) => { |
146 | 147 | if (!err) { |
... | ... | @@ -151,21 +152,20 @@ export default { |
151 | 152 | checkKey: this.currdatetime, |
152 | 153 | remember_me: rememberMe, |
153 | 154 | } |
154 | - console.log("登录参数", loginParams) | |
155 | 155 | this.Login(loginParams).then((res) => { |
156 | 156 | this.$emit('success', res.result) |
157 | 157 | }).catch((err) => { |
158 | 158 | this.$emit('fail', err) |
159 | + if (err.code == 499) { | |
160 | + this.$router.push({path: "/user/systemTokenModal"}) | |
161 | + } | |
159 | 162 | }); |
160 | 163 | } else { |
161 | 164 | this.$emit('validateFail') |
162 | 165 | } |
163 | 166 | }) |
164 | 167 | } |
165 | - | |
166 | - | |
167 | 168 | } |
168 | - | |
169 | 169 | } |
170 | 170 | </script> |
171 | 171 | |
... | ... |
ant-design-vue-jeecg/src/views/user/modules/SystemTokenForm.vue
0 → 100644
1 | +<template> | |
2 | + <div> | |
3 | + <a-form-model ref="form" :model="model" :rules="validatorRules"> | |
4 | + <a-form-model-item required prop="username"> | |
5 | + <a-input v-model="model.username" size="large" placeholder="请输入帐户名 / admin" @blur="getWarehouse"> | |
6 | + <a-icon slot="prefix" type="user" :style="{ color: 'rgba(0,0,0,.25)' }"/> | |
7 | + </a-input> | |
8 | + </a-form-model-item> | |
9 | + <a-form-model-item required prop="password"> | |
10 | + <a-input v-model="model.password" size="large" type="password" autocomplete="false" | |
11 | + placeholder="请输入密码 / 123456"> | |
12 | + <a-icon slot="prefix" type="lock" :style="{ color: 'rgba(0,0,0,.25)' }"/> | |
13 | + </a-input> | |
14 | + </a-form-model-item> | |
15 | + | |
16 | + <a-form-model-item prop="warehouseCode"> | |
17 | + <a-select | |
18 | + show-search | |
19 | + placeholder="请选择仓库" | |
20 | + option-filter-prop="label" | |
21 | + v-model="model.warehouseCode"> | |
22 | + <a-select-option v-for="item in warehouseList" :key="item.name" :value="item.code">{{ | |
23 | + item.name | |
24 | + }} | |
25 | + </a-select-option> | |
26 | + </a-select> | |
27 | + </a-form-model-item> | |
28 | + | |
29 | + </a-form-model> | |
30 | + </div> | |
31 | +</template> | |
32 | + | |
33 | +<script> | |
34 | +import {getAction} from '@/api/manage' | |
35 | +import Vue from 'vue' | |
36 | +import {mapActions} from 'vuex' | |
37 | +import {getWarehouseByUserCode} from '@/api/api' | |
38 | + | |
39 | +export default { | |
40 | + name: 'SystemTokenForm', | |
41 | + data() { | |
42 | + return { | |
43 | + requestCodeSuccess: false, | |
44 | + randCodeImage: '', | |
45 | + currdatetime: '', | |
46 | + loginType: 0, | |
47 | + warehouseList: {}, | |
48 | + querySource: {}, | |
49 | + model: { | |
50 | + username: '', | |
51 | + password: '', | |
52 | + warehouseCode: '', | |
53 | + // inputCode: '' | |
54 | + }, | |
55 | + validatorRules: { | |
56 | + username: [ | |
57 | + {required: true, message: '请输入用户名!'}, | |
58 | + {validator: this.handleUsernameOrEmail} | |
59 | + ], | |
60 | + password: [{ | |
61 | + required: true, message: '请输入密码!', validator: 'click' | |
62 | + }], | |
63 | + warehouseCode: [{ | |
64 | + required: true, message: '请选择仓库!', trigger: "change" , validator: 'click' | |
65 | + }], | |
66 | + } | |
67 | + } | |
68 | + }, | |
69 | + created() { | |
70 | + this.handleChangeCheckCode(); | |
71 | + this.getWarehouse(); | |
72 | + }, | |
73 | + | |
74 | + methods: { | |
75 | + ...mapActions(['Login']), | |
76 | + /**刷新验证码*/ | |
77 | + handleChangeCheckCode() { | |
78 | + this.currdatetime = new Date().getTime(); | |
79 | + // this.model.inputCode = '' | |
80 | + getAction(`/sys/randomImage/${this.currdatetime}`).then(res => { | |
81 | + if (res.success) { | |
82 | + this.randCodeImage = res.result | |
83 | + this.requestCodeSuccess = true | |
84 | + } else { | |
85 | + this.$message.error(res.message) | |
86 | + this.requestCodeSuccess = false | |
87 | + } | |
88 | + }).catch(() => { | |
89 | + this.requestCodeSuccess = false | |
90 | + }) | |
91 | + }, | |
92 | + | |
93 | + getWarehouse() { | |
94 | + const that = this; | |
95 | + this.querySource.username = that.model.username; | |
96 | + let obj = getWarehouseByUserCode(that.querySource); | |
97 | + obj.then((res) => { | |
98 | + that.warehouseList = res.result; | |
99 | + if (this.warehouseList != null) { | |
100 | + this.model.warehouseCode = this.warehouseList[0].code; | |
101 | + } | |
102 | + }) | |
103 | + }, | |
104 | + | |
105 | + // 判断登录类型 | |
106 | + handleUsernameOrEmail(rule, value, callback) { | |
107 | + const regex = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((\.[a-zA-Z0-9_-]{2,3}){1,2})$/; | |
108 | + if (regex.test(value)) { | |
109 | + this.loginType = 0 | |
110 | + } else { | |
111 | + this.loginType = 1 | |
112 | + } | |
113 | + callback() | |
114 | + }, | |
115 | + /** | |
116 | + * 验证字段 | |
117 | + * @param arr | |
118 | + * @param callback | |
119 | + */ | |
120 | + validateFields(arr, callback) { | |
121 | + let promiseArray = [] | |
122 | + for (let item of arr) { | |
123 | + let p = new Promise((resolve, reject) => { | |
124 | + this.$refs['form'].validateField(item, (err) => { | |
125 | + if (!err) { | |
126 | + resolve(); | |
127 | + } else { | |
128 | + reject(err); | |
129 | + } | |
130 | + }) | |
131 | + }); | |
132 | + promiseArray.push(p) | |
133 | + } | |
134 | + Promise.all(promiseArray).then(() => { | |
135 | + callback() | |
136 | + }).catch(err => { | |
137 | + callback(err) | |
138 | + }) | |
139 | + }, | |
140 | + acceptUsername(username) { | |
141 | + this.model['username'] = username | |
142 | + }, | |
143 | + // 账号密码登录 | |
144 | + handleLogin(rememberMe) { | |
145 | + this.validateFields(['username', 'password'], (err) => { | |
146 | + if (!err) { | |
147 | + let loginParams = { | |
148 | + username: this.model.username, | |
149 | + password: this.model.password, | |
150 | + warehouseCode: this.model.warehouseCode, | |
151 | + checkKey: this.currdatetime, | |
152 | + remember_me: rememberMe, | |
153 | + } | |
154 | + this.Login(loginParams).then((res) => { | |
155 | + this.$emit('success', res.result) | |
156 | + }).catch((err) => { | |
157 | + console.log(">>>>>>>>>err.message:", err.message) | |
158 | + this.$emit('fail', err) | |
159 | + this.$router.push({path: "/user/systemTokenModal"}).catch(() => { | |
160 | + | |
161 | + }) | |
162 | + }); | |
163 | + } else { | |
164 | + this.$emit('validateFail') | |
165 | + } | |
166 | + }) | |
167 | + } | |
168 | + } | |
169 | +} | |
170 | +</script> | |
171 | + | |
172 | +<style scoped> | |
173 | + | |
174 | +</style> | |
0 | 175 | \ No newline at end of file |
... | ... |
ant-design-vue-jeecg/src/views/user/modules/SystemTokenModal.vue
0 → 100644
1 | +<template> | |
2 | + <div class="main"> | |
3 | + <a-form-model class="user-layout-login" @keyup.enter.native="handleSubmit"> | |
4 | + <a-tabs :activeKey="customActiveKey" :tabBarStyle="{ textAlign: 'center', borderBottom: 'unset' }" @change="handleTabClick"> | |
5 | + <a-tab-pane key="tab1" tab="授权 TOKEN"> | |
6 | + <!-- <login-account ref="alogin" @validateFail="validateFail" @success="requestSuccess" @fail="requestFailed"></login-account> --> | |
7 | + </a-tab-pane> | |
8 | + <!-- <a-tab-pane key="tab2" tab="手机号登录"> | |
9 | + <login-phone ref="plogin" @validateFail="validateFail" @success="requestSuccess" @fail="requestFailed"></login-phone> | |
10 | + </a-tab-pane> --> | |
11 | + </a-tabs> | |
12 | + <a-form-model-item> | |
13 | + <a-input size="large" v-model="model.password" autocomplete="false" placeholder="请输入授权 TOKEN"/> | |
14 | + </a-form-model-item> | |
15 | + <a-form-item style="margin-top:24px"> | |
16 | + <a-button size="large" type="primary" htmlType="submit" class="login-button" :loading="loginBtn" @click.stop.prevent="handleSubmit" :disabled="loginBtn">确定 | |
17 | + </a-button> | |
18 | + </a-form-item> | |
19 | + </a-form-model> | |
20 | + <two-step-captcha v-if="requiredTwoStepCaptcha" :visible="stepCaptchaVisible" @success="stepCaptchaSuccess" @cancel="stepCaptchaCancel"></two-step-captcha> | |
21 | + <!-- <login-select-tenant ref="loginSelect" @success="loginSelectOk"></login-select-tenant> --> | |
22 | + <!-- <third-login ref="thirdLogin"></third-login>--> | |
23 | + </div> | |
24 | +</template> | |
25 | + | |
26 | + | |
27 | +<script> | |
28 | +import Vue from 'vue' | |
29 | +import {ACCESS_TOKEN, ENCRYPTED_STRING} from '@/store/mutation-types' | |
30 | +import TwoStepCaptcha from '@/components/tools/TwoStepCaptcha' | |
31 | +import {getEncryptedString} from '@/utils/encryption/aesEncrypt' | |
32 | +import {timeFix} from '@/utils/util' | |
33 | +import SystemTokenForm from './SystemTokenForm' | |
34 | + | |
35 | +export default { | |
36 | + components: { | |
37 | + TwoStepCaptcha, | |
38 | + SystemTokenForm | |
39 | + }, | |
40 | + data() { | |
41 | + return { | |
42 | + customActiveKey: 'tab1', | |
43 | + rememberMe: true, | |
44 | + loginBtn: false, | |
45 | + requiredTwoStepCaptcha: false, | |
46 | + stepCaptchaVisible: false, | |
47 | + querySource: {}, | |
48 | + encryptedString: { | |
49 | + key: "", | |
50 | + iv: "", | |
51 | + }, | |
52 | + model: { | |
53 | + password: '' | |
54 | + }, | |
55 | + } | |
56 | + }, | |
57 | + created() { | |
58 | + Vue.ls.remove(ACCESS_TOKEN) | |
59 | + this.getRouterData(); | |
60 | + this.rememberMe = true | |
61 | + }, | |
62 | + methods: { | |
63 | + handleTabClick(key) { | |
64 | + this.customActiveKey = key | |
65 | + }, | |
66 | + handleRememberMeChange(e) { | |
67 | + this.rememberMe = e.target.checked | |
68 | + }, | |
69 | + /**跳转到登录页面的参数-账号获取*/ | |
70 | + getRouterData() { | |
71 | + this.$nextTick(() => { | |
72 | + let temp = this.$route.params.username || this.$route.query.username || '' | |
73 | + if (temp) { | |
74 | + this.$refs.alogin.acceptUsername(temp) | |
75 | + } | |
76 | + }) | |
77 | + }, | |
78 | + //登录 | |
79 | + handleSubmit() { | |
80 | + this.loginBtn = true; | |
81 | + console.log('handleSubmit start') | |
82 | + this.handleLogin(this.rememberMe) | |
83 | + }, | |
84 | + // 校验失败 | |
85 | + validateFail() { | |
86 | + this.loginBtn = false; | |
87 | + }, | |
88 | + // 登录后台成功 | |
89 | + requestSuccess(loginResult) { | |
90 | + this.$refs.loginSelect.show(loginResult) | |
91 | + }, | |
92 | + //登录后台失败 | |
93 | + requestFailed(err) { | |
94 | + let description = ((err.response || {}).data || {}).message || err.message || "请求出现错误,请稍后再试" | |
95 | + this.$notification['error']({ | |
96 | + message: '登录失败', | |
97 | + description: description, | |
98 | + duration: 4, | |
99 | + }); | |
100 | + //账户密码登录错误后更新验证码 | |
101 | + if (this.customActiveKey === 'tab1' && description.indexOf('密码错误') > 0) { | |
102 | + this.$refs.alogin.handleChangeCheckCode() | |
103 | + } | |
104 | + this.loginBtn = false; | |
105 | + }, | |
106 | + loginSelectOk() { | |
107 | + this.loginSuccess() | |
108 | + }, | |
109 | + //登录成功 | |
110 | + loginSuccess() { | |
111 | + this.$router.push({path: "/dashboard/analysis"}); | |
112 | + this.$notification.success({ | |
113 | + message: '欢迎', | |
114 | + description: `${timeFix()},欢迎回来`, | |
115 | + }); | |
116 | + }, | |
117 | + insertTokenSuccess() { | |
118 | + this.$router.push({path: "/user/login"}); | |
119 | + this.$notification.success({ | |
120 | + message: '验证成功,请重新登录', | |
121 | + // description: `${timeFix()},欢迎回来`, | |
122 | + }); | |
123 | + }, | |
124 | + insertTokenError() { | |
125 | + this.$notification.error({ | |
126 | + message: '验证失败,请重新输入', | |
127 | + // description: `${timeFix()},欢迎回来`, | |
128 | + }); | |
129 | + this.loginBtn = false; | |
130 | + }, | |
131 | + stepCaptchaSuccess() { | |
132 | + this.loginSuccess() | |
133 | + }, | |
134 | + stepCaptchaCancel() { | |
135 | + this.Logout().then(() => { | |
136 | + this.loginBtn = false | |
137 | + this.stepCaptchaVisible = false | |
138 | + }) | |
139 | + }, | |
140 | + //获取密码加密规则 | |
141 | + getEncrypte() { | |
142 | + var encryptedString = Vue.ls.get(ENCRYPTED_STRING); | |
143 | + if (encryptedString == null) { | |
144 | + getEncryptedString().then((data) => { | |
145 | + this.encryptedString = data | |
146 | + }); | |
147 | + } else { | |
148 | + this.encryptedString = encryptedString; | |
149 | + } | |
150 | + }, | |
151 | + handleLogin(rememberMe) { | |
152 | + console.log('handleLogin start') | |
153 | + let loginParams = { | |
154 | + password: this.model.password, | |
155 | + } | |
156 | + // this.insertTokenSuccess(); | |
157 | + this.insertTokenError(); | |
158 | + // this.loginSelectOk(); | |
159 | + // this.Login(loginParams).then((res) => { | |
160 | + // this.$emit('success', res.result) | |
161 | + // }).catch((err) => { | |
162 | + // this.$emit('fail', err) | |
163 | + // }); | |
164 | + } | |
165 | + } | |
166 | +} | |
167 | +</script> | |
168 | +<style lang="less" scoped> | |
169 | +.user-layout-login { | |
170 | + label { | |
171 | + font-size: 14px; | |
172 | + } | |
173 | + | |
174 | + .getCaptcha { | |
175 | + display: block; | |
176 | + width: 100%; | |
177 | + height: 40px; | |
178 | + } | |
179 | + | |
180 | + .forge-password { | |
181 | + font-size: 14px; | |
182 | + } | |
183 | + | |
184 | + button.login-button { | |
185 | + padding: 0 15px; | |
186 | + font-size: 16px; | |
187 | + height: 40px; | |
188 | + width: 100%; | |
189 | + } | |
190 | + | |
191 | + .user-login-other { | |
192 | + text-align: left; | |
193 | + margin-top: 24px; | |
194 | + line-height: 22px; | |
195 | + | |
196 | + .item-icon { | |
197 | + font-size: 24px; | |
198 | + color: rgba(0, 0, 0, .2); | |
199 | + margin-left: 16px; | |
200 | + vertical-align: middle; | |
201 | + cursor: pointer; | |
202 | + transition: color .3s; | |
203 | + | |
204 | + &:hover { | |
205 | + color: #1890ff; | |
206 | + } | |
207 | + } | |
208 | + | |
209 | + .register { | |
210 | + float: right; | |
211 | + } | |
212 | + } | |
213 | + | |
214 | + .valid-error .ant-select-selection__placeholder { | |
215 | + color: #f5222d; | |
216 | + } | |
217 | +} | |
218 | +</style> | |
0 | 219 | \ No newline at end of file |
... | ... |
huaheng-wms-core/src/main/java/org/jeecg/modules/system/controller/LoginController.java
1 | 1 | package org.jeecg.modules.system.controller; |
2 | 2 | |
3 | -import cn.hutool.core.util.RandomUtil; | |
4 | -import com.alibaba.fastjson.JSONObject; | |
5 | -import com.aliyuncs.exceptions.ClientException; | |
6 | -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | |
7 | -import com.baomidou.mybatisplus.core.toolkit.IdWorker; | |
8 | -import io.swagger.annotations.Api; | |
9 | -import io.swagger.annotations.ApiOperation; | |
10 | -import lombok.extern.slf4j.Slf4j; | |
3 | +import java.io.File; | |
4 | +import java.io.FileOutputStream; | |
5 | +import java.io.IOException; | |
6 | +import java.util.ArrayList; | |
7 | +import java.util.Calendar; | |
8 | +import java.util.Date; | |
9 | +import java.util.GregorianCalendar; | |
10 | +import java.util.HashMap; | |
11 | +import java.util.List; | |
12 | +import java.util.Map; | |
13 | + | |
14 | +import javax.servlet.http.HttpServletRequest; | |
15 | +import javax.servlet.http.HttpServletResponse; | |
16 | + | |
11 | 17 | import org.apache.shiro.SecurityUtils; |
12 | 18 | import org.jeecg.common.api.vo.Result; |
13 | 19 | import org.jeecg.common.constant.CacheConstant; |
14 | 20 | import org.jeecg.common.constant.CommonConstant; |
15 | 21 | import org.jeecg.common.system.api.ISysBaseAPI; |
16 | 22 | import org.jeecg.common.system.util.JwtUtil; |
17 | -import org.jeecg.utils.HuahengJwtUtil; | |
18 | 23 | import org.jeecg.common.system.vo.LoginUser; |
19 | -import org.jeecg.common.util.*; | |
24 | +import org.jeecg.common.util.DySmsEnum; | |
25 | +import org.jeecg.common.util.DySmsHelper; | |
26 | +import org.jeecg.common.util.MD5Util; | |
27 | +import org.jeecg.common.util.PasswordUtil; | |
28 | +import org.jeecg.common.util.RedisUtil; | |
29 | +import org.jeecg.common.util.oConvertUtils; | |
20 | 30 | import org.jeecg.common.util.encryption.EncryptedString; |
21 | 31 | import org.jeecg.modules.base.service.BaseCommonService; |
22 | -import org.jeecg.modules.message.websocket.WebSocket; | |
23 | 32 | import org.jeecg.modules.system.entity.SysDepart; |
24 | 33 | import org.jeecg.modules.system.entity.SysTenant; |
25 | 34 | import org.jeecg.modules.system.entity.SysUser; |
26 | 35 | import org.jeecg.modules.system.model.SysLoginModel; |
27 | -import org.jeecg.modules.system.service.*; | |
36 | +import org.jeecg.modules.system.model.SystemAuthenticationModel; | |
37 | +import org.jeecg.modules.system.service.ISysDepartService; | |
38 | +import org.jeecg.modules.system.service.ISysDictService; | |
39 | +import org.jeecg.modules.system.service.ISysLogService; | |
40 | +import org.jeecg.modules.system.service.ISysTenantService; | |
41 | +import org.jeecg.modules.system.service.ISysUserService; | |
28 | 42 | import org.jeecg.modules.system.util.RandImageUtil; |
43 | +import org.jeecg.utils.HuahengJwtUtil; | |
29 | 44 | import org.jeecg.utils.StringUtils; |
45 | +import org.jeecg.utils.support.ApiAuthentication; | |
46 | +import org.jeecg.utils.support.SystemRSA256Key; | |
30 | 47 | import org.springframework.beans.BeanUtils; |
31 | 48 | import org.springframework.beans.factory.annotation.Autowired; |
49 | +import org.springframework.context.annotation.Bean; | |
50 | +import org.springframework.core.io.DefaultResourceLoader; | |
51 | +import org.springframework.core.io.ResourceLoader; | |
32 | 52 | import org.springframework.data.redis.core.RedisTemplate; |
33 | -import org.springframework.web.bind.annotation.*; | |
53 | +import org.springframework.util.FileCopyUtils; | |
54 | +import org.springframework.web.bind.annotation.GetMapping; | |
55 | +import org.springframework.web.bind.annotation.PathVariable; | |
56 | +import org.springframework.web.bind.annotation.PostMapping; | |
57 | +import org.springframework.web.bind.annotation.RequestBody; | |
58 | +import org.springframework.web.bind.annotation.RequestMapping; | |
59 | +import org.springframework.web.bind.annotation.RequestMethod; | |
60 | +import org.springframework.web.bind.annotation.RequestParam; | |
61 | +import org.springframework.web.bind.annotation.ResponseBody; | |
62 | +import org.springframework.web.bind.annotation.RestController; | |
34 | 63 | |
35 | -import javax.annotation.Resource; | |
36 | -import javax.servlet.http.HttpServletRequest; | |
37 | -import javax.servlet.http.HttpServletResponse; | |
38 | -import java.util.*; | |
64 | +import com.alibaba.fastjson.JSONObject; | |
65 | +import com.aliyuncs.exceptions.ClientException; | |
66 | +import com.auth0.jwt.JWT; | |
67 | +import com.auth0.jwt.JWTVerifier; | |
68 | +import com.auth0.jwt.algorithms.Algorithm; | |
69 | +import com.auth0.jwt.exceptions.JWTVerificationException; | |
70 | +import com.auth0.jwt.interfaces.DecodedJWT; | |
71 | +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | |
72 | +import com.baomidou.mybatisplus.core.toolkit.IdWorker; | |
73 | + | |
74 | +import cn.hutool.core.util.RandomUtil; | |
75 | +import io.swagger.annotations.Api; | |
76 | +import io.swagger.annotations.ApiOperation; | |
77 | +import lombok.extern.slf4j.Slf4j; | |
39 | 78 | |
40 | 79 | /** |
41 | 80 | * @Author scott |
... | ... | @@ -48,26 +87,34 @@ import java.util.*; |
48 | 87 | public class LoginController { |
49 | 88 | @Autowired |
50 | 89 | private ISysUserService sysUserService; |
90 | + | |
51 | 91 | @Autowired |
52 | 92 | private ISysBaseAPI sysBaseAPI; |
93 | + | |
53 | 94 | @Autowired |
54 | 95 | private ISysLogService logService; |
96 | + | |
55 | 97 | @Autowired |
56 | 98 | private RedisUtil redisUtil; |
99 | + | |
57 | 100 | @Autowired |
58 | 101 | private ISysDepartService sysDepartService; |
102 | + | |
59 | 103 | @Autowired |
60 | 104 | private ISysTenantService sysTenantService; |
105 | + | |
61 | 106 | @Autowired |
62 | 107 | public RedisTemplate<String, ?> redisTemplate; |
108 | + | |
63 | 109 | @Autowired |
64 | 110 | private ISysDictService sysDictService; |
111 | + | |
65 | 112 | @Autowired |
66 | 113 | private BaseCommonService baseCommonService; |
67 | 114 | |
68 | 115 | @ApiOperation("登录接口") |
69 | 116 | @RequestMapping(value = "/login", method = RequestMethod.POST) |
70 | - public Result<JSONObject> login(@RequestBody SysLoginModel sysLoginModel) { | |
117 | + public Result<JSONObject> login(@RequestBody SysLoginModel sysLoginModel) throws IOException { | |
71 | 118 | Result<JSONObject> result = new Result<JSONObject>(); |
72 | 119 | String username = sysLoginModel.getUsername(); |
73 | 120 | String password = sysLoginModel.getPassword(); |
... | ... | @@ -104,7 +151,6 @@ public class LoginController { |
104 | 151 | if (!result.isSuccess()) { |
105 | 152 | return result; |
106 | 153 | } |
107 | - | |
108 | 154 | // 2. 校验用户名或密码是否正确 |
109 | 155 | String userpassword = PasswordUtil.encrypt(username, password, sysUser.getSalt()); |
110 | 156 | String syspassword = sysUser.getPassword(); |
... | ... | @@ -116,6 +162,10 @@ public class LoginController { |
116 | 162 | result.error500("请选择仓库编码"); |
117 | 163 | return result; |
118 | 164 | } |
165 | +// result = HuahengJwtUtil.checkSystemToken(); | |
166 | +// if (!result.isSuccess()) { | |
167 | +// return result; | |
168 | +// } | |
119 | 169 | // 用户登录信息 |
120 | 170 | result = userInfo(sysUser, warehouseCode); |
121 | 171 | // update-begin--Author:liusq Date:20210126 for:登录成功,删除redis中的验证码 |
... | ... | @@ -128,6 +178,46 @@ public class LoginController { |
128 | 178 | return result; |
129 | 179 | } |
130 | 180 | |
181 | + @ApiOperation("系统认证API") | |
182 | + @RequestMapping(value = "/systemAuthentication", method = RequestMethod.POST) | |
183 | + public Result<JSONObject> systemAuthentication(@RequestBody SystemAuthenticationModel systemAuthenticationModel) throws IOException { | |
184 | + Result<JSONObject> result = new Result<JSONObject>(); | |
185 | + if (StringUtils.isEmpty(systemAuthenticationModel.getToken())) { | |
186 | + result.error500("请输入TOKEN"); | |
187 | + return result; | |
188 | + } | |
189 | + FileOutputStream outputStream = null; | |
190 | + try { | |
191 | + Algorithm algorithm = Algorithm.RSA256(new SystemRSA256Key().getPublicKey(), new SystemRSA256Key().getPrivateKey()); | |
192 | + JWTVerifier verifier = | |
193 | + JWT.require(algorithm).withClaim("operator", HuahengJwtUtil.HUAHENG_SYSTEM_ID).withIssuer(HuahengJwtUtil.HUAHENG_SYSTEM_ID).build(); | |
194 | + DecodedJWT jwt = verifier.verify(systemAuthenticationModel.getToken()); | |
195 | + new ApiAuthentication.ApiAuthenticationBuild().operator(jwt.getClaim("operator").asString()).audience(jwt.getAudience().get(0)).issuer(jwt.getIssuer()) | |
196 | + .issuedAt(jwt.getIssuedAt()).expireDateTime(jwt.getExpiresAt()).bulid(); | |
197 | + | |
198 | + String path = System.getProperties().getProperty("user.dir") + "\\SystemToken.txt"; | |
199 | + File file = new File(path); | |
200 | + outputStream = new FileOutputStream(file, false); | |
201 | + FileCopyUtils.copy(systemAuthenticationModel.getToken().getBytes(), outputStream); | |
202 | + | |
203 | + } catch (JWTVerificationException e) { | |
204 | + log.error(e.getMessage()); | |
205 | + result.error500("认证失败"); | |
206 | + return result; | |
207 | + } finally { | |
208 | + if (outputStream != null) { | |
209 | + outputStream.close(); | |
210 | + } | |
211 | + } | |
212 | + result.setMessage("认证成功"); | |
213 | + return result; | |
214 | + } | |
215 | + | |
216 | + @Bean | |
217 | + public ResourceLoader createResourceLoader() { | |
218 | + return new DefaultResourceLoader(); | |
219 | + } | |
220 | + | |
131 | 221 | /** |
132 | 222 | * 【vue3专用】获取用户信息 |
133 | 223 | */ |
... | ... | @@ -654,7 +744,7 @@ public class LoginController { |
654 | 744 | return Result.error("用户名不能为空"); |
655 | 745 | } |
656 | 746 | } |
657 | - | |
747 | + | |
658 | 748 | /** |
659 | 749 | * 获取当前用户的可用仓库列表 |
660 | 750 | */ |
... | ... | @@ -678,7 +768,7 @@ public class LoginController { |
678 | 768 | } |
679 | 769 | return result; |
680 | 770 | } |
681 | - | |
771 | + | |
682 | 772 | @RequestMapping(value = "/selectUserWarehouse", method = RequestMethod.PUT) |
683 | 773 | public Result<JSONObject> selectUserWarehouses(HttpServletRequest request, @RequestBody Map<String, String> params) { |
684 | 774 | Result<JSONObject> result = new Result<JSONObject>(); |
... | ... |
huaheng-wms-core/src/main/java/org/jeecg/modules/system/model/SystemAuthenticationModel.java
0 → 100644
1 | +package org.jeecg.modules.system.model; | |
2 | + | |
3 | +import io.swagger.annotations.ApiModel; | |
4 | +import io.swagger.annotations.ApiModelProperty; | |
5 | +import lombok.Data; | |
6 | + | |
7 | +/** | |
8 | + * 系统认证对象 | |
9 | + * @Author scott | |
10 | + * @since 2019-01-18 | |
11 | + */ | |
12 | +@Data | |
13 | +@ApiModel(value = "系统认证对象", description = "系统认证对象") | |
14 | +public class SystemAuthenticationModel { | |
15 | + | |
16 | + @ApiModelProperty(value = "TOKEN") | |
17 | + private String token; | |
18 | + | |
19 | +} | |
... | ... |
huaheng-wms-core/src/main/java/org/jeecg/utils/HuahengJwtUtil.java
1 | 1 | package org.jeecg.utils; |
2 | 2 | |
3 | +import java.io.File; | |
4 | +import java.io.FileInputStream; | |
5 | +import java.io.IOException; | |
6 | +import java.io.InputStream; | |
3 | 7 | import java.lang.reflect.Field; |
4 | 8 | import java.util.Arrays; |
5 | 9 | import java.util.Date; |
... | ... | @@ -8,19 +12,25 @@ import java.util.UUID; |
8 | 12 | |
9 | 13 | import javax.servlet.http.HttpServletRequest; |
10 | 14 | |
15 | +import org.apache.commons.io.IOUtils; | |
11 | 16 | import org.apache.shiro.SecurityUtils; |
17 | +import org.jeecg.common.api.vo.Result; | |
12 | 18 | import org.jeecg.common.exception.JeecgBootException; |
13 | 19 | import org.jeecg.common.system.vo.LoginUser; |
14 | 20 | import org.jeecg.common.util.oConvertUtils; |
15 | 21 | import org.jeecg.utils.support.ApiAuthentication; |
16 | 22 | import org.jeecg.utils.support.RSA256Key; |
23 | +import org.jeecg.utils.support.SystemAuthentication; | |
24 | +import org.jeecg.utils.support.SystemRSA256Key; | |
17 | 25 | import org.springframework.stereotype.Component; |
18 | 26 | import org.springframework.util.CollectionUtils; |
19 | 27 | |
28 | +import com.alibaba.fastjson.JSONObject; | |
20 | 29 | import com.auth0.jwt.JWT; |
21 | 30 | import com.auth0.jwt.JWTVerifier; |
22 | 31 | import com.auth0.jwt.algorithms.Algorithm; |
23 | 32 | import com.auth0.jwt.exceptions.JWTDecodeException; |
33 | +import com.auth0.jwt.exceptions.TokenExpiredException; | |
24 | 34 | import com.auth0.jwt.interfaces.DecodedJWT; |
25 | 35 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
26 | 36 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
... | ... | @@ -134,7 +144,7 @@ public class HuahengJwtUtil { |
134 | 144 | lambdaQueryWrapper.apply("warehouse_code = {0}", warehouseCode); |
135 | 145 | } |
136 | 146 | } |
137 | - | |
147 | + | |
138 | 148 | public static <T> void setWarehouseCode(QueryWrapper<T> queryWrapper, Class<T> clazz, HttpServletRequest request) { |
139 | 149 | List<String> roles = HuahengJwtUtil.getRolesByToken(request); |
140 | 150 | String warehouseCode = HuahengJwtUtil.getWarehouseCodeByToken(request); |
... | ... | @@ -200,8 +210,7 @@ public class HuahengJwtUtil { |
200 | 210 | * @return |
201 | 211 | */ |
202 | 212 | public static String sign(ApiAuthentication apiAuthentication) { |
203 | - RSA256Key rsa256Key = new RSA256Key(); // 获取公钥/私钥 | |
204 | - Algorithm algorithm = Algorithm.RSA256(rsa256Key.getPublicKey(), rsa256Key.getPrivateKey()); | |
213 | + Algorithm algorithm = Algorithm.RSA256(new RSA256Key().getPublicKey(), new RSA256Key().getPrivateKey()); | |
205 | 214 | return JWT.create().withClaim("operator", apiAuthentication.getOperator()) // 创建Token 操作人 |
206 | 215 | .withAudience(apiAuthentication.getAudience()) // Token 使用方 |
207 | 216 | .withIssuer(apiAuthentication.getIssuer()) // Token 发布者 |
... | ... | @@ -210,6 +219,16 @@ public class HuahengJwtUtil { |
210 | 219 | .withJWTId(UUID.randomUUID().toString()).sign(algorithm); |
211 | 220 | } |
212 | 221 | |
222 | + public static String sign(SystemAuthentication systemAuthentication) { | |
223 | + Algorithm algorithm = Algorithm.RSA256(new SystemRSA256Key().getPublicKey(), new SystemRSA256Key().getPrivateKey()); | |
224 | + return JWT.create().withClaim("operator", systemAuthentication.getOperator()) // 创建Token 操作人 | |
225 | + .withAudience(systemAuthentication.getAudience()) // Token 使用方 | |
226 | + .withIssuer(systemAuthentication.getIssuer()) // Token 发布者 | |
227 | + .withIssuedAt(DateUtil.date()) // 生成签名时间 | |
228 | + .withExpiresAt(systemAuthentication.getExpireDateTime()) // 过期时间 | |
229 | + .withJWTId(UUID.randomUUID().toString()).sign(algorithm); | |
230 | + } | |
231 | + | |
213 | 232 | public static String getAudienceByToken(String token) { |
214 | 233 | RSA256Key rsa256Key = new RSA256Key(); // 获取公钥/私钥 |
215 | 234 | Algorithm algorithm = Algorithm.RSA256(rsa256Key.getPublicKey(), rsa256Key.getPrivateKey()); |
... | ... | @@ -245,6 +264,37 @@ public class HuahengJwtUtil { |
245 | 264 | } |
246 | 265 | } |
247 | 266 | |
267 | + public static Result<JSONObject> checkSystemToken() throws IOException { | |
268 | + Result<JSONObject> result = new Result<JSONObject>(); | |
269 | + InputStream inputStream = null; | |
270 | + try { | |
271 | + String path = System.getProperties().getProperty("user.dir") + "\\SystemToken.txt"; | |
272 | + File file = new File(path); | |
273 | + inputStream = new FileInputStream(file); | |
274 | + String systemToken = IOUtils.toString(inputStream, "utf-8"); | |
275 | + | |
276 | + Algorithm algorithm = Algorithm.RSA256(new SystemRSA256Key().getPublicKey(), new SystemRSA256Key().getPrivateKey()); | |
277 | + JWTVerifier verifier = | |
278 | + JWT.require(algorithm).withClaim("operator", HuahengJwtUtil.HUAHENG_SYSTEM_ID).withIssuer(HuahengJwtUtil.HUAHENG_SYSTEM_ID).build(); | |
279 | + DecodedJWT jwt = verifier.verify(systemToken); | |
280 | + new ApiAuthentication.ApiAuthenticationBuild().operator(jwt.getClaim("operator").asString()).audience(jwt.getAudience().get(0)).issuer(jwt.getIssuer()) | |
281 | + .issuedAt(jwt.getIssuedAt()).expireDateTime(jwt.getExpiresAt()).bulid(); | |
282 | + } catch (TokenExpiredException e) { | |
283 | + result.setSuccess(false); | |
284 | + result.setCode(499); | |
285 | + result.setMessage("系统授权期限已过期"); | |
286 | + } catch (Exception e) { | |
287 | + result.setSuccess(false); | |
288 | + result.setCode(499); | |
289 | + result.setMessage("系统授权TOKEN无效"); | |
290 | + } finally { | |
291 | + if (inputStream != null) { | |
292 | + inputStream.close(); | |
293 | + } | |
294 | + } | |
295 | + return result; | |
296 | + } | |
297 | + | |
248 | 298 | /** |
249 | 299 | * 生成第三方系统HTTP访问TOKEN |
250 | 300 | * @author TanYibin |
... | ... | @@ -253,6 +303,9 @@ public class HuahengJwtUtil { |
253 | 303 | * @throws Exception |
254 | 304 | */ |
255 | 305 | public static void main(String[] args) throws Exception { |
306 | + | |
307 | + System.out.println("-------------------------------------API TOKEN-------------------------------------"); | |
308 | + // 生成API TOKEN | |
256 | 309 | ApiAuthentication apiAuthentication = new ApiAuthentication(); |
257 | 310 | // 生成TOKEN必填参数 |
258 | 311 | apiAuthentication.setOperator("youjie"); // Token提供方 |
... | ... | @@ -260,19 +313,41 @@ public class HuahengJwtUtil { |
260 | 313 | apiAuthentication.setExpireDateTime(DateUtil.parse("2099-12-31 23:59:59", DatePattern.NORM_DATETIME_PATTERN)); // Token失效时间 |
261 | 314 | |
262 | 315 | String tokenString = sign(apiAuthentication); |
263 | - System.out.println("HuahengJwtUtil.sign(apiAuthentication) Token:" + tokenString); | |
316 | + System.out.println("API Token:\r\n" + tokenString); | |
264 | 317 | |
265 | - RSA256Key rsa256Key = new RSA256Key(); // 获取公钥/私钥 | |
266 | - Algorithm algorithm = Algorithm.RSA256(rsa256Key.getPublicKey(), rsa256Key.getPrivateKey()); | |
318 | + Algorithm algorithm = Algorithm.RSA256(new RSA256Key().getPublicKey(), new RSA256Key().getPrivateKey()); | |
267 | 319 | // Reusable verifier instance 可复用的验证实例 |
268 | 320 | JWTVerifier verifier = JWT.require(algorithm).withIssuer(HuahengJwtUtil.HUAHENG_SYSTEM_ID).build(); |
269 | 321 | DecodedJWT jwt = verifier.verify(tokenString); |
270 | 322 | System.out.println(); |
271 | 323 | System.out.println("jwt.getId():" + jwt.getId()); |
272 | 324 | System.out.println("jwt.getClaim(operator):" + jwt.getClaim("operator").asString()); |
273 | - System.out.println("jwt.getAudience():" + Arrays.toString(jwt.getAudience().toArray())); | |
274 | 325 | System.out.println("jwt.getIssuer():" + jwt.getIssuer()); |
326 | + System.out.println("jwt.getAudience():" + Arrays.toString(jwt.getAudience().toArray())); | |
275 | 327 | System.out.println("jwt.getIssuedAt():" + DateUtil.format(jwt.getIssuedAt(), DatePattern.NORM_DATETIME_PATTERN)); |
276 | 328 | System.out.println("jwt.getExpiresAt():" + DateUtil.format(jwt.getExpiresAt(), DatePattern.NORM_DATETIME_PATTERN)); |
329 | + | |
330 | + System.out.println("-------------------------------------系统激活码TOKEN-------------------------------------"); | |
331 | + // 生成系统激活码TOKEN | |
332 | + SystemAuthentication systemAuthentication = new SystemAuthentication(); | |
333 | + // 生成TOKEN必填参数 | |
334 | + systemAuthentication.setAudience("湘潭崇德"); // Token使用方 | |
335 | + systemAuthentication.setExpireDateTime(DateUtil.parse("2099-12-31 23:59:59", DatePattern.NORM_DATETIME_PATTERN)); // Token失效时间 | |
336 | + | |
337 | + String systemTokenString = sign(systemAuthentication); | |
338 | + System.out.println("System Token:\r\n" + systemTokenString); | |
339 | + | |
340 | + Algorithm systemAlgorithm = Algorithm.RSA256(new SystemRSA256Key().getPublicKey(), new SystemRSA256Key().getPrivateKey()); | |
341 | + // Reusable verifier instance 可复用的验证实例 | |
342 | + JWTVerifier systemVerifier = JWT.require(systemAlgorithm).withIssuer(HuahengJwtUtil.HUAHENG_SYSTEM_ID).build(); | |
343 | + DecodedJWT systemJwt = systemVerifier.verify(systemTokenString); | |
344 | + System.out.println(); | |
345 | + System.out.println("systemJwt.getId():" + systemJwt.getId()); | |
346 | + System.out.println("systemJwt.getClaim(operator):" + systemJwt.getClaim("operator").asString()); | |
347 | + System.out.println("systemJwt.getIssuer():" + systemJwt.getIssuer()); | |
348 | + System.out.println("systemJwt.getAudience():" + Arrays.toString(systemJwt.getAudience().toArray())); | |
349 | + System.out.println("systemJwt.getIssuedAt():" + DateUtil.format(systemJwt.getIssuedAt(), DatePattern.NORM_DATETIME_PATTERN)); | |
350 | + System.out.println("systemJwt.getExpiresAt():" + DateUtil.format(systemJwt.getExpiresAt(), DatePattern.NORM_DATETIME_PATTERN)); | |
351 | + | |
277 | 352 | } |
278 | 353 | } |
... | ... |
huaheng-wms-core/src/main/java/org/jeecg/utils/support/SystemAuthentication.java
0 → 100644
1 | +package org.jeecg.utils.support; | |
2 | + | |
3 | +import java.util.Date; | |
4 | + | |
5 | +import org.jeecg.utils.HuahengJwtUtil; | |
6 | + | |
7 | +import cn.hutool.core.date.DatePattern; | |
8 | +import cn.hutool.core.date.DateUtil; | |
9 | +import lombok.Data; | |
10 | + | |
11 | +/** | |
12 | + * 系统认证Token对象 | |
13 | + * @author TanYibin | |
14 | + * @createDate 2023年2月14日 | |
15 | + */ | |
16 | +@Data | |
17 | +public class SystemAuthentication { | |
18 | + | |
19 | + private static final ThreadLocal<SystemAuthentication> REQUEST_HEADER_CONTEXT_THREAD_LOCAL = new ThreadLocal<>(); | |
20 | + | |
21 | + /** Token提供方 */ | |
22 | + private String operator = HuahengJwtUtil.HUAHENG_SYSTEM_ID; | |
23 | + | |
24 | + /** Token使用方 */ | |
25 | + private String audience = "Unknown"; // 观众,相当于接受者 | |
26 | + | |
27 | + /** Token签发方(WMS) */ | |
28 | + private String issuer = HuahengJwtUtil.HUAHENG_SYSTEM_ID; | |
29 | + | |
30 | + /** Token签发时间 */ | |
31 | + private Date issuedAt; | |
32 | + | |
33 | + /** Token失效时间 */ | |
34 | + private Date expireDateTime; | |
35 | + | |
36 | + public SystemAuthentication() {} | |
37 | + | |
38 | + public static SystemAuthentication getInstance() { | |
39 | + return REQUEST_HEADER_CONTEXT_THREAD_LOCAL.get(); | |
40 | + } | |
41 | + | |
42 | + public void setContext(SystemAuthentication context) { | |
43 | + REQUEST_HEADER_CONTEXT_THREAD_LOCAL.set(context); | |
44 | + } | |
45 | + | |
46 | + public static void clean() { | |
47 | + REQUEST_HEADER_CONTEXT_THREAD_LOCAL.remove(); | |
48 | + } | |
49 | + | |
50 | + private SystemAuthentication(SystemAuthenticationBuild systemAuthenticationBuild) { | |
51 | + this.operator = systemAuthenticationBuild.operator; | |
52 | + this.audience = systemAuthenticationBuild.audience; | |
53 | + this.issuer = systemAuthenticationBuild.issuer; | |
54 | + this.issuedAt = systemAuthenticationBuild.issuedAt; | |
55 | + this.expireDateTime = systemAuthenticationBuild.expireDateTime; | |
56 | + setContext(this); | |
57 | + } | |
58 | + | |
59 | + public static class SystemAuthenticationBuild { | |
60 | + | |
61 | + /** Token提供方 */ | |
62 | + private String operator; | |
63 | + | |
64 | + /** Token使用方 */ | |
65 | + private String audience; // 观众,相当于接受者 | |
66 | + | |
67 | + /** Token签发方(WMS) */ | |
68 | + private String issuer = HuahengJwtUtil.HUAHENG_SYSTEM_ID; | |
69 | + | |
70 | + /** Token签发时间 */ | |
71 | + private Date issuedAt; | |
72 | + | |
73 | + /** Token失效时间 */ | |
74 | + private Date expireDateTime; | |
75 | + | |
76 | + public SystemAuthenticationBuild operator(String operator) { | |
77 | + this.operator = operator; | |
78 | + return this; | |
79 | + } | |
80 | + | |
81 | + public SystemAuthenticationBuild audience(String audience) { | |
82 | + this.audience = audience; | |
83 | + return this; | |
84 | + } | |
85 | + | |
86 | + public SystemAuthenticationBuild issuer(String issuer) { | |
87 | + this.issuer = issuer; | |
88 | + return this; | |
89 | + } | |
90 | + | |
91 | + public SystemAuthenticationBuild issuedAt(Date issuedAt) { | |
92 | + this.issuedAt = issuedAt; | |
93 | + return this; | |
94 | + } | |
95 | + | |
96 | + public SystemAuthenticationBuild expireDateTime(Date expireDateTime) { | |
97 | + this.expireDateTime = expireDateTime; | |
98 | + return this; | |
99 | + } | |
100 | + | |
101 | + public SystemAuthentication bulid() { | |
102 | + return new SystemAuthentication(this); | |
103 | + } | |
104 | + } | |
105 | + | |
106 | +} | |
... | ... |
huaheng-wms-core/src/main/java/org/jeecg/utils/support/SystemRSA256Key.java
0 → 100644
1 | +package org.jeecg.utils.support; | |
2 | + | |
3 | +import java.security.interfaces.RSAPrivateKey; | |
4 | +import java.security.interfaces.RSAPublicKey; | |
5 | + | |
6 | +import org.jeecg.utils.SecretKeyUtils; | |
7 | +import org.springframework.stereotype.Component; | |
8 | + | |
9 | +import lombok.Data; | |
10 | + | |
11 | +@Data | |
12 | +@Component | |
13 | +public class SystemRSA256Key { | |
14 | + | |
15 | + /** 第三方HTTP访问 公钥 */ | |
16 | + private RSAPublicKey publicKey = | |
17 | + (RSAPublicKey)SecretKeyUtils.getPublicKey("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCdEKYyMFZJpE0t+37vOhMRJ0AV2JQRP9k0qAn5wHejNl7a12mrQSYPi" | |
18 | + + "riOEvR9wlQJBDy/cakSbN7G1s4jVyVv/9RTl7RMMzNlh3q6yspHR2CNE2aAsAxJx2xDyJb7Yq3xAbdfVMCjkufbonhMm2i21oaS5p9vLWHRMoEODbIFBwIDAQAB"); | |
19 | + | |
20 | + /** 第三方HTTP访问 私钥 */ | |
21 | + private RSAPrivateKey privateKey = | |
22 | + (RSAPrivateKey)SecretKeyUtils.getPrivateKey("MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJ0QpjIwVkmkTS37fu86ExEnQBXYlBE/2TSoCfnAd6M" | |
23 | + + "2XtrXaatBJg+KuI4S9H3CVAkEPL9xqRJs3sbWziNXJW//1FOXtEwzM2WHerrKykdHYI0TZoCwDEnHbEPIlvtirfEBt19UwKOS59uieEybaLbWhpLmn28tYdEygQ4NsgUH" | |
24 | + + "AgMBAAECgYEAiVzaPOKRVG5hIWnmJYqAymutXG3BcSSJ7cdYkhiFiTQv2Oyz+ZZMlyMXLQne0W122TvfdP8OgpK8cuHB/p5kmhzkuVQqIE+AYVK3qb+8k46SiltcTWB36" | |
25 | + + "I5CiJyVVJB3Wl5X/YzAMkuo+rS9Nn6CMiOpwUM/HxYR4TqX/Xz/LeECQQD2CjXCg32IPGTCiBVgHlyGkSHAbwxPj4zN0H4AAdtayplka2rGOXws7jSfWxrWWxzA0HlGq7" | |
26 | + + "bMmIyY2AkAH/kTAkEAo2xdSdJLdCGlKD3uS1MOKsf7nkJmC4eBuN3dDH/3gMTVIeeMsvwAPKws6L6P9bd3uG8h+0fXFYx5OyBhmAKWvQJATNKNTKnf1Vz+HRt+iR+Rxla" | |
27 | + + "kkkBaOLFaxpy16uypgCTIVmmP0kr6sdDCz4sTyyBxzuaJJ37QOfvb0pGJ5ecVzwJAY7OmCnapH/Wy3CVEb2IBf6o4YWoi9Z+7TbzVsl2T81SiryekGEJUJq/oSiqQi5le" | |
28 | + + "CgCLG9HNb9Ee2Sq9P888hQJAY3paj/+a7Wjx5WhVBLxfzHKIcZ9tCgi5sOneCEKaV1eIGhOrWFcnBqc7VNYIatnRWwJccpzRUwWXmtr9Q8mWpA=="); | |
29 | +} | |
... | ... |
huaheng-wms-core/src/main/resources/application-dev.yml
... | ... | @@ -208,7 +208,7 @@ jeecg: |
208 | 208 | #webapp文件路径 |
209 | 209 | webapp: ./webapp |
210 | 210 | shiro: |
211 | - excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**,/sys/getWarehouseByUserCode,/api/**,/sys/cas/client/validateLogin,/sys/common/static/** | |
211 | + excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**,/sys/getWarehouseByUserCode,/api/**,/sys/cas/client/validateLogin,/sys/common/static/**,/sys/systemAuthentication | |
212 | 212 | #阿里云oss存储和大鱼短信秘钥配置 |
213 | 213 | oss: |
214 | 214 | accessKey: ?? |
... | ... |
huaheng-wms-core/src/main/resources/application-prod.yml
... | ... | @@ -208,7 +208,7 @@ jeecg: |
208 | 208 | #webapp文件路径 |
209 | 209 | webapp: ./webapp |
210 | 210 | shiro: |
211 | - excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**,/sys/getWarehouseByUserCode,/api/**,/sys/cas/client/validateLogin,/sys/common/static/** | |
211 | + excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**,/sys/getWarehouseByUserCode,/api/**,/sys/cas/client/validateLogin,/sys/common/static/**,/sys/systemAuthentication | |
212 | 212 | #阿里云oss存储和大鱼短信秘钥配置 |
213 | 213 | oss: |
214 | 214 | accessKey: ?? |
... | ... |
huaheng-wms-core/src/main/resources/application-test.yml
... | ... | @@ -209,7 +209,7 @@ jeecg: |
209 | 209 | #webapp文件路径 |
210 | 210 | webapp: ./webapp |
211 | 211 | shiro: |
212 | - excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**,/sys/getWarehouseByUserCode,/api/**,/sys/cas/client/validateLogin,/sys/common/static/** | |
212 | + excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**,/sys/getWarehouseByUserCode,/api/**,/sys/cas/client/validateLogin,/sys/common/static/**,/sys/systemAuthentication | |
213 | 213 | #阿里云oss存储和大鱼短信秘钥配置 |
214 | 214 | oss: |
215 | 215 | accessKey: ?? |
... | ... |