From 60c525d2f48b0f3bf02b447faf6e61388033785a Mon Sep 17 00:00:00 2001 From: fit2cloud-chenyw Date: Fri, 19 Feb 2021 14:34:46 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=89=8D=E7=AB=AF=E6=B7=BB=E5=8A=A0rsa?= =?UTF-8?q?=E9=9D=9E=E5=AF=B9=E7=A7=B0=E5=8A=A0=E5=AF=86=E7=AD=96=E7=95=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fit2cloud/commons/auth/api/UserApi.java | 12 +- .../commons/auth/config/RsaProperties.java | 17 +++ .../commons/auth/dao/ExtUserMapper.java | 16 ++- .../commons/auth/service/UserService.java | 4 +- .../fit2cloud/commons/auth/util/RsaUtil.java | 131 ++++++++++++++++++ .../src/main/resources/application.properties | 2 +- fit2cloud-view/package.json | 3 +- fit2cloud-view/src/api/user-token.js | 8 +- fit2cloud-view/src/permission.js | 12 +- 9 files changed, 183 insertions(+), 22 deletions(-) diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/api/UserApi.java b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/api/UserApi.java index 71a8b84c5a..c94440fc82 100644 --- a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/api/UserApi.java +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/api/UserApi.java @@ -1,11 +1,14 @@ package com.fit2cloud.commons.auth.api; import cn.hutool.core.util.StrUtil; +import cn.hutool.crypto.asymmetric.RSA; import com.fit2cloud.commons.auth.bean.LoginDto; import com.fit2cloud.commons.auth.bean.UserBean; import com.fit2cloud.commons.auth.bean.UserInfo; +import com.fit2cloud.commons.auth.config.RsaProperties; import com.fit2cloud.commons.auth.service.UserService; import com.fit2cloud.commons.auth.util.JWTUtil; +import com.fit2cloud.commons.auth.util.RsaUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import org.springframework.web.context.request.RequestContextHolder; @@ -23,18 +26,21 @@ public class UserApi { private UserService userService; @PostMapping("/login") - public Map login(@RequestBody LoginDto loginDto){ + public Map login(@RequestBody LoginDto loginDto) throws Exception{ String username = loginDto.getUsername(); String password = loginDto.getPassword(); String realPwd = userService.getPassword(username); + if (StrUtil.isEmpty(realPwd)){ throw new RuntimeException("没有该用户!"); } - if (!StrUtil.equals(realPwd, password)){ + String pwd = RsaUtil.decryptByPrivateKey(RsaProperties.privateKey, password); + String realpwd = RsaUtil.decryptByPrivateKey(RsaProperties.privateKey, realPwd); + if (!StrUtil.equals(pwd, realpwd)){ throw new RuntimeException("密码错误!"); } Map result = new HashMap<>(); - result.put("token", JWTUtil.sign(username, password)); + result.put("token", JWTUtil.sign(username, realpwd)); return result; } diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/config/RsaProperties.java b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/config/RsaProperties.java index e69de29bb2..06028eb011 100644 --- a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/config/RsaProperties.java +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/config/RsaProperties.java @@ -0,0 +1,17 @@ +package com.fit2cloud.commons.auth.config; + +import lombok.Data; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Data +@Component +public class RsaProperties { + + public static String privateKey; + + @Value("${rsa.private_key}") + public void setPrivateKey(String privateKey) { + RsaProperties.privateKey = privateKey; + } +} diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/dao/ExtUserMapper.java b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/dao/ExtUserMapper.java index 4d7292291e..f65d39a9ba 100644 --- a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/dao/ExtUserMapper.java +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/dao/ExtUserMapper.java @@ -3,6 +3,7 @@ package com.fit2cloud.commons.auth.dao; import com.fit2cloud.commons.auth.bean.ExtPermissionBean; +import com.fit2cloud.commons.auth.entity.SysUser; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Select; @@ -11,20 +12,23 @@ import java.util.List; @Mapper public interface ExtUserMapper { - @Select("select password from sys_user where user_id = #{userId,jdbcType=VARCHAR} ") - String getPassword(String userId); + @Select("select password from sys_user where username = #{userName,jdbcType=VARCHAR} ") + String getPassword(String userName); - @Select("select role_id from sys_users_roles where user_id = #{userId,jdbcType=VARCHAR} ") - List getRole(String userId); + @Select("select role_id from sys_users_roles where username = #{userName,jdbcType=VARCHAR} ") + List getRole(String userName); @Select({ "select sm.permission ", "from sys_users_roles sur ", "LEFT JOIN sys_roles_menus srm on srm.role_id = sur.role_id ", "LEFT JOIN sys_menu sm on sm.menu_id = srm.menu_id ", - "where sur.user_id = #{userId,jdbcType=VARCHAR} " + "where sur.username = #{userName,jdbcType=VARCHAR} " }) - List getPermission(String userId); + List getPermission(String userName); + + @Select("select * from sys_user where username = #{username,jdbcType=VARCHAR}") + SysUser getUser(String username); @Select("select path,permission from sys_menu where path is not null") List getPermissions(); diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/service/UserService.java b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/service/UserService.java index 27295e6626..b60890e701 100644 --- a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/service/UserService.java +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/service/UserService.java @@ -3,6 +3,7 @@ package com.fit2cloud.commons.auth.service; import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.fit2cloud.commons.auth.bean.UserBean; import com.fit2cloud.commons.auth.dao.ExtUserMapper; import com.fit2cloud.commons.auth.entity.SysUser; @@ -21,7 +22,8 @@ public class UserService { @Autowired(required = false) private SysUserMapper sysUserMapper; public UserBean getUser(String username){ - SysUser sysUser = sysUserMapper.selectById(username); + + SysUser sysUser = extUserMapper.getUser(username); if (ObjectUtil.isNull(sysUser))return null; String password = sysUser.getPassword(); diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/util/RsaUtil.java b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/util/RsaUtil.java index e69de29bb2..77864b4db4 100644 --- a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/util/RsaUtil.java +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/util/RsaUtil.java @@ -0,0 +1,131 @@ +package com.fit2cloud.commons.auth.util; + + + +import org.apache.commons.codec.binary.Base64; + +import javax.crypto.Cipher; +import java.security.*; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; + +public class RsaUtil { + + + /** + * 公钥解密 + * + * @param publicKeyText 公钥 + * @param text 待解密的信息 + * @return / + * @throws Exception / + */ + public static String decryptByPublicKey(String publicKeyText, String text) throws Exception { + X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyText)); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec); + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.DECRYPT_MODE, publicKey); + byte[] result = cipher.doFinal(Base64.decodeBase64(text)); + return new String(result); + } + + /** + * 私钥加密 + * + * @param privateKeyText 私钥 + * @param text 待加密的信息 + * @return / + * @throws Exception / + */ + public static String encryptByPrivateKey(String privateKeyText, String text) throws Exception { + PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyText)); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec); + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.ENCRYPT_MODE, privateKey); + byte[] result = cipher.doFinal(text.getBytes()); + return Base64.encodeBase64String(result); + } + + /** + * 私钥解密 + * + * @param privateKeyText 私钥 + * @param text 待解密的文本 + * @return / + * @throws Exception / + */ + public static String decryptByPrivateKey(String privateKeyText, String text) throws Exception { + PKCS8EncodedKeySpec pkcs8EncodedKeySpec5 = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyText)); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec5); + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.DECRYPT_MODE, privateKey); + byte[] result = cipher.doFinal(Base64.decodeBase64(text)); + return new String(result); + } + + /** + * 公钥加密 + * + * @param publicKeyText 公钥 + * @param text 待加密的文本 + * @return / + */ + public static String encryptByPublicKey(String publicKeyText, String text) throws Exception { + X509EncodedKeySpec x509EncodedKeySpec2 = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyText)); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec2); + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.ENCRYPT_MODE, publicKey); + byte[] result = cipher.doFinal(text.getBytes()); + return Base64.encodeBase64String(result); + } + + /** + * 构建RSA密钥对 + * + * @return / + * @throws NoSuchAlgorithmException / + */ + public static RsaKeyPair generateKeyPair() throws NoSuchAlgorithmException { + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); + keyPairGenerator.initialize(1024); + KeyPair keyPair = keyPairGenerator.generateKeyPair(); + RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic(); + RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate(); + String publicKeyString = Base64.encodeBase64String(rsaPublicKey.getEncoded()); + String privateKeyString = Base64.encodeBase64String(rsaPrivateKey.getEncoded()); + return new RsaKeyPair(publicKeyString, privateKeyString); + } + + + /** + * RSA密钥对对象 + */ + public static class RsaKeyPair { + + private final String publicKey; + private final String privateKey; + + public RsaKeyPair(String publicKey, String privateKey) { + this.publicKey = publicKey; + this.privateKey = privateKey; + } + + public String getPublicKey() { + return publicKey; + } + + public String getPrivateKey() { + return privateKey; + } + + } + + + +} diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/resources/application.properties b/fit2cloud-commons/fit2cloud-common-auth/src/main/resources/application.properties index f6aa23d3e1..874716de0b 100644 --- a/fit2cloud-commons/fit2cloud-common-auth/src/main/resources/application.properties +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/resources/application.properties @@ -1,2 +1,2 @@ spring.cache.type=ehcache -spring.cache.ehcache.config=ehcache.xml \ No newline at end of file +spring.cache.ehcache.config=ehcache.xml diff --git a/fit2cloud-view/package.json b/fit2cloud-view/package.json index 5f74afdb2a..53f4d4347c 100644 --- a/fit2cloud-view/package.json +++ b/fit2cloud-view/package.json @@ -22,7 +22,8 @@ "nprogress": "^0.2.0", "vue": "^2.6.11", "vue-i18n": "^8.22.4", - "vuex": "^3.6.0" + "vuex": "^3.6.0", + "jsencrypt": "^3.0.0-rc.1" }, "devDependencies": { "@vue/cli-plugin-babel": "~4.5.0", diff --git a/fit2cloud-view/src/api/user-token.js b/fit2cloud-view/src/api/user-token.js index ba12b7d64b..5dc6435d97 100644 --- a/fit2cloud-view/src/api/user-token.js +++ b/fit2cloud-view/src/api/user-token.js @@ -2,19 +2,19 @@ import {get, post, put} from "@/plugins/request" export function login(data) { - return post("/samples/user-token/login", data) + return post("/login", data) } export function logout() { - return post("/samples/user-token/logout") + return post("/logout") } export function getCurrentUser() { - return get("/samples/user-token/current") + return get("/info") } export function updateInfo(data) { - return put("/samples/user-token/update", data) + return put("/update", data) } diff --git a/fit2cloud-view/src/permission.js b/fit2cloud-view/src/permission.js index d431c23090..7e8b5e7e9a 100644 --- a/fit2cloud-view/src/permission.js +++ b/fit2cloud-view/src/permission.js @@ -1,6 +1,7 @@ import router from './router' import store from './store' import NProgress from 'nprogress' +import { getToken } from '@/utils/token' import 'nprogress/nprogress.css' NProgress.configure({showSpinner: false}) // NProgress Configuration @@ -13,12 +14,12 @@ const generateRoutes = async (to, from, next) => { next() } else { try { - const {roles} = await store.dispatch('user/getCurrentUser') + const {roles} = await store.dispatch('user-token/getCurrentUser') const accessRoutes = await store.dispatch('permission/generateRoutes', roles) router.addRoutes(accessRoutes) next({...to, replace: true}) } catch (error) { - await store.dispatch('user/logout') + await store.dispatch('user-token/logout') next(`/login?redirect=${to.path}`) NProgress.done() } @@ -28,10 +29,9 @@ const generateRoutes = async (to, from, next) => { // 路由前置钩子,根据实际需求修改 router.beforeEach(async (to, from, next) => { NProgress.start() - - const isLogin = await store.dispatch('user/isLogin') // 或者user-token/isLogin - - if (isLogin) { + // const isLogin = await store.dispatch('user-token/isLogin') // 或者user-token/isLogin + const hasToken = getToken() + if (hasToken) { if (to.path === '/login') { next({path: '/'}) NProgress.done()