Skip to content

Commit

Permalink
Encrypted transmission of login password (opengoofy#1316)
Browse files Browse the repository at this point in the history
* feat(login): opengoofy#1300 Encrypted transmission of login password

* feat(login): opengoofy#1300 Modify the comments to English

* ref(login): opengoofy#1300 Restore static resources

---------

Co-authored-by: limingwei <[email protected]>
Co-authored-by: Serenity <[email protected]>
  • Loading branch information
3 people authored May 22, 2023
1 parent dd2c27b commit a9ca0a7
Show file tree
Hide file tree
Showing 6 changed files with 252 additions and 115 deletions.
2 changes: 2 additions & 0 deletions threadpool/console/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,11 @@
},
"dependencies": {
"axios": ">=0.18.1",
"buffer": "^6.0.3",
"clipboard": "2.0.4",
"codemirror": "5.45.0",
"core-js": "^3.26.0",
"crypto": "^1.0.1",
"echarts": "^5.2.2",
"element-ui": "^2.15.7",
"fuse.js": "3.4.4",
Expand Down
255 changes: 142 additions & 113 deletions threadpool/console/src/store/modules/user.js
Original file line number Diff line number Diff line change
@@ -1,126 +1,155 @@
import { login } from '@/api/user';
import { getToken, setToken, removeToken } from '@/utils/auth';
import router, { resetRouter } from '@/router';
import {login} from '@/api/user';
import {getToken, removeToken, setToken} from '@/utils/auth';
import router, {resetRouter} from '@/router';
import {Buffer} from 'buffer'
import crypto from 'crypto'

const state = {
token: getToken(),
name: '',
avatar: '',
introduction: '',
roles: [],
token: getToken(),
name: '',
avatar: '',
introduction: '',
roles: [],
};

const mutations = {
SET_TOKEN: (state, token) => {
state.token = token;
},
SET_INTRODUCTION: (state, introduction) => {
state.introduction = introduction;
},
SET_NAME: (state, name) => {
state.name = name;
},
SET_AVATAR: (state, avatar) => {
state.avatar = avatar;
},
SET_ROLES: (state, roles) => {
state.roles = roles;
},
SET_TOKEN: (state, token) => {
state.token = token;
},
SET_INTRODUCTION: (state, introduction) => {
state.introduction = introduction;
},
SET_NAME: (state, name) => {
state.name = name;
},
SET_AVATAR: (state, avatar) => {
state.avatar = avatar;
},
SET_ROLES: (state, roles) => {
state.roles = roles;
},
};

const actions = {
// user login
login({ commit }, userInfo) {
const { username, password } = userInfo;
return new Promise((resolve, reject) => {
login({ username: username.trim(), password: password, rememberMe: 1 })
.then((response) => {
const { data } = response;
const { roles } = response;
commit('SET_TOKEN', data);
localStorage.setItem('roles', JSON.stringify(roles));
localStorage.setItem('USER_ROLE', roles[0]);
setToken(data);
resolve();
})
.catch((error) => {
alert('登录失败');
reject(error);
// user login
login({commit}, userInfo) {
const {username, password} = userInfo;
return new Promise((resolve, reject) => {
let key = actions.genKey();
let encodePassword = actions.encrypt(password, key)
key = key.split("").reverse().join("")
login({username: username.trim(), password: encodePassword, tag: key, rememberMe: 1})
.then((response) => {
const {data} = response;
const {roles} = response;
commit('SET_TOKEN', data);
localStorage.setItem('roles', JSON.stringify(roles));
localStorage.setItem('USER_ROLE', roles[0]);
setToken(data);
resolve();
})
.catch((error) => {
// alert('登录失败');
reject(error);
});
});
});
},

// get user info
getInfo({ commit, state }) {
return new Promise((resolve, reject) => {
const data = {};
data.roles = JSON.parse(localStorage.getItem('roles'));
commit('SET_ROLES', data.roles);
resolve(data);
});
},

// user logout
logout({ commit, state }) {
// return new Promise((resolve, reject) => {
// logout(state.token).then(() => {
// commit('SET_TOKEN', '')
// commit('SET_ROLES', [])
// removeToken()
// resetRouter()
// resolve()
// }).catch(error => {
// reject(error)
// })
// })
return new Promise((resolve) => {
commit('SET_TOKEN', '');
commit('SET_ROLES', []);
removeToken();
resetRouter();
resolve();
});
},

// remove token
resetToken({ commit }) {
return new Promise((resolve) => {
commit('SET_TOKEN', '');
commit('SET_ROLES', []);
removeToken();
resolve();
});
},

// dynamically modify permissions
changeRoles({ commit, dispatch }, role) {
return new Promise(async (resolve) => {
const token = role + '-token';

commit('SET_TOKEN', token);
setToken(token);

const { roles } = await dispatch('getInfo');

resetRouter();

// generate accessible routes map based on roles
const accessRoutes = await dispatch('permission/generateRoutes', roles, { root: true });

// dynamically add accessible routes
router.addRoutes(accessRoutes);

// reset visited views and cached views
dispatch('tagsView/delAllViews', null, { root: true });

resolve();
});
},
},


// get user info
getInfo({commit, state}) {
return new Promise((resolve, reject) => {
const data = {};
data.roles = JSON.parse(localStorage.getItem('roles'));
commit('SET_ROLES', data.roles);
resolve(data);
});
},

// user logout
logout({commit, state}) {
// return new Promise((resolve, reject) => {
// logout(state.token).then(() => {
// commit('SET_TOKEN', '')
// commit('SET_ROLES', [])
// removeToken()
// resetRouter()
// resolve()
// }).catch(error => {
// reject(error)
// })
// })
return new Promise((resolve) => {
commit('SET_TOKEN', '');
commit('SET_ROLES', []);
removeToken();
resetRouter();
resolve();
});
},

// remove token
resetToken({commit}) {
return new Promise((resolve) => {
commit('SET_TOKEN', '');
commit('SET_ROLES', []);
removeToken();
resolve();
});
},

// dynamically modify permissions
changeRoles({commit, dispatch}, role) {
return new Promise(async (resolve) => {
const token = role + '-token';

commit('SET_TOKEN', token);
setToken(token);

const {roles} = await dispatch('getInfo');

resetRouter();

// generate accessible routes map based on roles
const accessRoutes = await dispatch('permission/generateRoutes', roles, {root: true});

// dynamically add accessible routes
router.addRoutes(accessRoutes);

// reset visited views and cached views
dispatch('tagsView/delAllViews', null, {root: true});

resolve();
});
},
genKey() {
let chars = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
let result = '';
for (let i = 16; i > 0; --i) result += chars[Math.floor(Math.random() * chars.length)];
return result;
},
encrypt(msg, key) {
try {
let pwd = Buffer.from(key)
let iv = crypto.randomBytes(12)
let cipher = crypto.createCipheriv('aes-128-gcm', pwd, iv)
let enc = cipher.update(msg, 'utf8', 'base64')
enc += cipher.final('base64')
let tags = cipher.getAuthTag()
enc = Buffer.from(enc, 'base64')
let totalLength = iv.length + enc.length + tags.length
let bufferMsg = Buffer.concat([iv, enc, tags], totalLength)
return bufferMsg.toString('base64')
} catch (e) {
console.log("Encrypt is error", e)
return null
}
},
};

export default {
namespaced: true,
state,
mutations,
actions,
namespaced: true,
state,
mutations,
actions,
};
4 changes: 2 additions & 2 deletions threadpool/console/src/views/login/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,8 @@ export default {
this.$router.push({ path: this.redirect || '/', query: this.otherQuery });
this.loading = false;
})
.catch(() => {
console.log('error catch.');
.catch((e) => {
console.log('error catch.',e);
this.loading = false;
});
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@

import cn.hippo4j.auth.model.biz.user.JwtUser;
import cn.hippo4j.auth.model.biz.user.LoginUser;
import cn.hippo4j.auth.toolkit.AESUtil;
import cn.hippo4j.auth.toolkit.JwtTokenUtil;
import cn.hippo4j.auth.toolkit.ReturnT;
import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.server.common.base.Results;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.codec.DecodingException;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
Expand All @@ -38,6 +40,7 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
Expand Down Expand Up @@ -69,10 +72,17 @@ public Authentication attemptAuthentication(HttpServletRequest request,
Authentication authenticate = null;
try {
LoginUser loginUser = new ObjectMapper().readValue(request.getInputStream(), LoginUser.class);
String key = new StringBuffer(loginUser.getTag()).reverse().toString();
String password = AESUtil.decrypt(loginUser.getPassword(), key);
loginUser.setPassword(password);

request.setAttribute("loginUser", loginUser);
rememberMe.set(loginUser.getRememberMe());
authenticate = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(loginUser.getUsername(), loginUser.getPassword(), new ArrayList()));
} catch (GeneralSecurityException e) {
log.warn("Password decode exception: {}", e.getMessage());
throw new DecodingException(e.getMessage());
} catch (UsernameNotFoundException e) {
log.warn("User {} not found", e.getMessage());
throw e;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
*/
@Data
public class LoginUser {
/**
* encode key reverse
*/
private String tag;

/**
* username
Expand Down
Loading

0 comments on commit a9ca0a7

Please sign in to comment.