From a4e63f780930c4080a70dacbf9c9fd6fdce0081d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=B5=B7?= <10402852@qq.com> Date: Sat, 21 Sep 2024 14:41:27 +0800 Subject: [PATCH] 'commit' --- .idea/compiler.xml | 4 + .idea/encodings.xml | 2 + .idea/misc.xml | 2 + dsBase/pom.xml | 28 ++++ .../Controller/LoginPersonController.java | 154 +++++++++--------- .../java/com/dsideal/base/Util/JwtUtil.java | 73 +++++++++ dsBase/src/main/resource/application_dev.yaml | 2 + dsBase/src/main/resource/application_pro.yaml | 2 + dsBase/target/classes/application_dev.yaml | 2 + dsBase/target/classes/application_pro.yaml | 2 + 10 files changed, 196 insertions(+), 75 deletions(-) create mode 100644 dsBase/src/main/java/com/dsideal/base/Util/JwtUtil.java diff --git a/.idea/compiler.xml b/.idea/compiler.xml index 91f04974..3af024ac 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -34,6 +34,9 @@ + + + diff --git a/.idea/encodings.xml b/.idea/encodings.xml index 205b71e9..5c2c4568 100644 --- a/.idea/encodings.xml +++ b/.idea/encodings.xml @@ -9,6 +9,8 @@ + + diff --git a/.idea/misc.xml b/.idea/misc.xml index a9fc6872..e71b4fc1 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -13,10 +13,12 @@ diff --git a/dsBase/pom.xml b/dsBase/pom.xml index b45d15e4..db4041a7 100644 --- a/dsBase/pom.xml +++ b/dsBase/pom.xml @@ -247,6 +247,34 @@ snakeyaml ${snakeyaml.version} + + + + + io.jsonwebtoken + jjwt + 0.7.0 + + + javax.xml.bind + jaxb-api + 2.3.0 + + + com.sun.xml.bind + jaxb-impl + 2.3.0 + + + com.sun.xml.bind + jaxb-core + 2.3.0 + + + javax.activation + activation + 1.1.1 + diff --git a/dsBase/src/main/java/com/dsideal/base/LoginPerson/Controller/LoginPersonController.java b/dsBase/src/main/java/com/dsideal/base/LoginPerson/Controller/LoginPersonController.java index 27b5d188..6b9b75f2 100644 --- a/dsBase/src/main/java/com/dsideal/base/LoginPerson/Controller/LoginPersonController.java +++ b/dsBase/src/main/java/com/dsideal/base/LoginPerson/Controller/LoginPersonController.java @@ -27,94 +27,98 @@ public class LoginPersonController extends Controller { LoginPersonModel model = new LoginPersonModel(); @Before({POST.class}) - public void doLogin(String username, String password) { + public void doLogin(String username, String password, String platform) { + if (StrKit.isBlank(platform)) { + platform = "WEB"; + } JSONObject resultJson = new JSONObject(); - try { - if (StrKit.isBlank(username)) { - resultJson.put("success", false); - resultJson.put("msg", "用户名不允许为空!"); - renderJson(resultJson); - return; - } - if (StrKit.isBlank(password)) { - resultJson.put("success", false); - resultJson.put("msg", "密码不允许为空!"); - renderJson(resultJson); - return; - } + if (StrKit.isBlank(username)) { + resultJson.put("success", false); + resultJson.put("msg", "用户名不允许为空!"); + renderJson(resultJson); + return; + } + if (StrKit.isBlank(password)) { + resultJson.put("success", false); + resultJson.put("msg", "密码不允许为空!"); + renderJson(resultJson); + return; + } - //检查缓存中此账号错误了几次 - String PassWordKey = "WrongPassWord_" + username; - int ErrCnt = 4; //最多允许错几次 4+1 - int cntNum = 0; //错几次了 - if (RedisKit.exists(PassWordKey)) cntNum = Integer.parseInt(RedisKit.get(PassWordKey).toString()); + //检查缓存中此账号错误了几次 + String PassWordKey = "WrongPassWord_" + username; + int ErrCnt = 4; //最多允许错几次 4+1 + int cntNum = 0; //错几次了 + if (RedisKit.exists(PassWordKey)) cntNum = Integer.parseInt(RedisKit.get(PassWordKey).toString()); + if (cntNum > ErrCnt) { + resultJson.put("success", false); + resultJson.put("msg", "账号被停用5分钟,请稍后再试!"); + renderJson(resultJson); + return; + } + //与前端配合RSA通用加密解密 + try { + password = RsaUtils.decryptDataOnJava(password, RsaUtils.PRIVATEKEY); + } catch (Exception err) { + password = "!@#$%^&&*^*&(*)(*_)^%^$%$^%$^%"; + } + String passwordEncode = CommonUtil.getLdapPassword(password); + BaseModel bm = new BaseModel(); + Map loginMap = bm.getLoginInfoByUserName(username); + if (loginMap == null || !passwordEncode.equals(loginMap.get("password").toString())) { + //扩展支持连续输入用户名密码错误,停用账号5分钟功能 2022.06.07 + cntNum = 1; + if (RedisKit.exists(PassWordKey)) + cntNum = Integer.parseInt(RedisKit.get(PassWordKey).toString()) + cntNum; + RedisKit.set(PassWordKey, String.valueOf(cntNum)); + RedisKit.expire(PassWordKey, 60 * 5); if (cntNum > ErrCnt) { resultJson.put("success", false); - resultJson.put("msg", "账号被停用5分钟,请稍后再试!"); + resultJson.put("msg", "密码连续输入" + (ErrCnt + 1) + "次全部错误,账号将被停用5分钟!"); renderJson(resultJson); return; } - //与前端配合RSA通用加密解密 - try { - password = RsaUtils.decryptDataOnJava(password, RsaUtils.PRIVATEKEY); - } catch (Exception err) { - password = "!@#$%^&&*^*&(*)(*_)^%^$%$^%$^%"; - } - String passwordEncode = CommonUtil.getLdapPassword(password); - BaseModel bm = new BaseModel(); - Map loginMap = bm.getLoginInfoByUserName(username); - if (loginMap == null || !passwordEncode.equals(loginMap.get("password").toString())) { - //扩展支持连续输入用户名密码错误,停用账号5分钟功能 2022.06.07 - cntNum = 1; - if (RedisKit.exists(PassWordKey)) - cntNum = Integer.parseInt(RedisKit.get(PassWordKey).toString()) + cntNum; - RedisKit.set(PassWordKey, String.valueOf(cntNum)); - RedisKit.expire(PassWordKey, 60 * 5); - if (cntNum > ErrCnt) { - resultJson.put("success", false); - resultJson.put("msg", "密码连续输入" + (ErrCnt + 1) + "次全部错误,账号将被停用5分钟!"); - renderJson(resultJson); - return; - } - if (cntNum == ErrCnt) { - resultJson.put("success", false); - resultJson.put("msg", "用户名或密码连续错误,你还有1次机会,再次错误后账号将被封掉5分钟!"); - renderJson(resultJson); - return; - } + if (cntNum == ErrCnt) { resultJson.put("success", false); - resultJson.put("msg", "用户名或密码错误!"); + resultJson.put("msg", "用户名或密码连续错误,你还有1次机会,再次错误后账号将被封掉5分钟!"); renderJson(resultJson); return; } - //去掉限制 - RedisKit.del(PassWordKey); - //防止用户攻击修改Cookie - Map _map = new HashMap(); - _map.put("identity_id", loginMap.get("identity_id")); - _map.put("person_id", loginMap.get("person_id")); - _map.put("bureau_id", loginMap.get("bureau_id")); - - String token = CommonUtil.Sign(_map, BaseApplication.PropKit.get("jwt.CookieMd5SingPwd")); - CookieUtil.set(getResponse(), "identity_id", loginMap.get("identity_id").toString(), false, true); - CookieUtil.set(getResponse(), "person_id", loginMap.get("person_id").toString(), false, true); - CookieUtil.set(getResponse(), "bureau_id", loginMap.get("bureau_id").toString(), false, true); - CookieUtil.set(getResponse(), "token", token, false, true); - - resultJson.put("success", true); - resultJson.put("identity_id", loginMap.get("identity_id").toString()); - resultJson.put("person_id", loginMap.get("person_id").toString()); - resultJson.put("bureau_id", loginMap.get("bureau_id").toString()); - resultJson.put("person_name", loginMap.get("person_name").toString()); - //根据人员id,获取所有单位信息 - Record r = bm.getBureauInfoByPersonId(loginMap.get("person_id").toString()); - if (r != null) resultJson.put("bureau_name", r.getStr("bureau_name")); - renderJson(resultJson); - } catch (Exception e) { resultJson.put("success", false); - resultJson.put("msg", "登录异常!"); + resultJson.put("msg", "用户名或密码错误!"); renderJson(resultJson); + return; } + //去掉限制 + RedisKit.del(PassWordKey); + //防止用户攻击修改Cookie + Map _map = new HashMap(); + _map.put("identity_id", loginMap.get("identity_id")); + _map.put("person_id", loginMap.get("person_id")); + _map.put("bureau_id", loginMap.get("bureau_id")); + + String token = CommonUtil.Sign(_map, BaseApplication.PropKit.get("jwt.CookieMd5SingPwd")); + CookieUtil.set(getResponse(), "identity_id", loginMap.get("identity_id").toString(), false, true); + CookieUtil.set(getResponse(), "person_id", loginMap.get("person_id").toString(), false, true); + CookieUtil.set(getResponse(), "bureau_id", loginMap.get("bureau_id").toString(), false, true); + CookieUtil.set(getResponse(), "token", token, false, true); + //添加返回的Token JWT + String jwtToken = JwtUtil.generateToken(Integer.parseInt(loginMap.get("identity_id").toString()), loginMap.get("person_id").toString(), loginMap.get("bureau_id").toString()); + resultJson.put("success", true); + resultJson.put("identity_id", loginMap.get("identity_id").toString()); + resultJson.put("person_id", loginMap.get("person_id").toString()); + resultJson.put("bureau_id", loginMap.get("bureau_id").toString()); + resultJson.put("person_name", loginMap.get("person_name").toString()); + resultJson.put("jwt", jwtToken); + //将此人员的权限信息写入Pika,如果后面的要求登录互踢,可以用来处理互踢 + //处理逻辑就是:检查此jwt是不是在Pika中存在,存在就是系统派发出去,并且是最后一次用户在此平台登录的TOKEN + //如果不存在,就表示此token已过期,踢出即可。 + RedisKit.set("jwt_" + platform + "_" + loginMap.get("person_id").toString(), jwtToken); + //根据人员id,获取所有单位信息 + Record r = bm.getBureauInfoByPersonId(loginMap.get("person_id").toString()); + if (r != null) resultJson.put("bureau_name", r.getStr("bureau_name")); + renderJson(resultJson); + } @@ -356,7 +360,7 @@ public class LoginPersonController extends Controller { renderFile(new File(excelFile), filename); } - static{ + static { System.setProperty("java.awt.headless", "true"); } /*****打印帐号和输出EXCEL的功能结束*********************************************************/ diff --git a/dsBase/src/main/java/com/dsideal/base/Util/JwtUtil.java b/dsBase/src/main/java/com/dsideal/base/Util/JwtUtil.java new file mode 100644 index 00000000..2255993b --- /dev/null +++ b/dsBase/src/main/java/com/dsideal/base/Util/JwtUtil.java @@ -0,0 +1,73 @@ +package com.dsideal.base.Util; + +import cn.hutool.core.date.DateTime; +import com.dsideal.base.BaseApplication; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; + +import java.nio.charset.StandardCharsets; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +public class JwtUtil { + public static final String AUTHORIZATION_STARTER = "Bearer "; + public static final String SECRET = BaseApplication.PropKit.get("SECRET"); + + /** + * 功能:黄海开发的生成JWT函数 + * + * @param identity_id 身份ID + * @param person_id 人员ID + * @param bureau_id 机构ID + * @return JWT签名 + */ + public static String generateToken(int identity_id, String person_id, String bureau_id) { + // 获取当前日期和时间 + Date now = new Date(); + // 格式化日期 + Map claims = new HashMap<>(); + claims.put("create_time", now.toString()); + claims.put("identity_id", identity_id); + claims.put("person_id", person_id); + claims.put("bureau_id", bureau_id); + return AUTHORIZATION_STARTER + Jwts.builder().setClaims(claims).signWith(SignatureAlgorithm.HS256, SECRET).compact(); + } + + public static Claims getClaims(String token) { + if (token.contains(AUTHORIZATION_STARTER)) { + token = token.replace(AUTHORIZATION_STARTER, ""); + } + Claims claims; + try { + claims = Jwts.parser() + .setSigningKey(SECRET) + .parseClaimsJws(token) + .getBody(); + } catch (Exception e) { + try { + claims = Jwts.parser() + .setSigningKey(SECRET.getBytes(StandardCharsets.UTF_8)) + .parseClaimsJws(token) + .getBody(); + } catch (Exception err) { + claims = null; + } + } + return claims; + } + + public static void main(String[] args) { + //GwApplication gw = new GwApplication(); + String token = generateToken(4, "0b64e31e-a85e-43eb-ba5f-3088d986a8da", "3f7f4c90-645a-4fb9-9902-447846cf1dcc"); + /** + 结论: + 1、JWT的里面有三个关键信息,一个是identity_id,另一个是person_id,还有一个bureau_id + */ + Claims claims = getClaims(token); + System.out.println(claims.get("identity_id")); + System.out.println(claims.get("person_id")); + System.out.println(claims.get("bureau_id")); + } +} diff --git a/dsBase/src/main/resource/application_dev.yaml b/dsBase/src/main/resource/application_dev.yaml index 038a01bc..746c9655 100644 --- a/dsBase/src/main/resource/application_dev.yaml +++ b/dsBase/src/main/resource/application_dev.yaml @@ -1,5 +1,7 @@ # 上传文件的临时路径 uploadTempPath: c:/Windows/Temp +# JWT +SECRET: ZXZnZWVr5b+r5LmQ5L2g55qE5Ye66KGM mysql: # 数据库信息 diff --git a/dsBase/src/main/resource/application_pro.yaml b/dsBase/src/main/resource/application_pro.yaml index c70f6ba5..8bcd10b9 100644 --- a/dsBase/src/main/resource/application_pro.yaml +++ b/dsBase/src/main/resource/application_pro.yaml @@ -1,5 +1,7 @@ # 上传文件的临时路径 uploadTempPath: /tmp +# JWT +SECRET: ZXZnZWVr5b+r5LmQ5L2g55qE5Ye66KGM mysql: # 数据库信息 diff --git a/dsBase/target/classes/application_dev.yaml b/dsBase/target/classes/application_dev.yaml index 038a01bc..746c9655 100644 --- a/dsBase/target/classes/application_dev.yaml +++ b/dsBase/target/classes/application_dev.yaml @@ -1,5 +1,7 @@ # 上传文件的临时路径 uploadTempPath: c:/Windows/Temp +# JWT +SECRET: ZXZnZWVr5b+r5LmQ5L2g55qE5Ye66KGM mysql: # 数据库信息 diff --git a/dsBase/target/classes/application_pro.yaml b/dsBase/target/classes/application_pro.yaml index c70f6ba5..8bcd10b9 100644 --- a/dsBase/target/classes/application_pro.yaml +++ b/dsBase/target/classes/application_pro.yaml @@ -1,5 +1,7 @@ # 上传文件的临时路径 uploadTempPath: /tmp +# JWT +SECRET: ZXZnZWVr5b+r5LmQ5L2g55qE5Ye66KGM mysql: # 数据库信息