Session登录失败限制 & RSA密码加密
# Session登录失败限制
# LoginSessionUtil
package com.datanew.base.util;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpSession;
import java.util.Date;
import java.util.HashMap;
@Component
public class LoginSessionUtil {
public static Integer failNum;
public static Long lockTime;
//yml文件读取允许失败次数
@Value("${datanew.failNum}")
private void setFailNum(Integer failNum) {
LoginSessionUtil.failNum = failNum;
}
//yml读取配置锁定时长
@Value("${datanew.lockTime}")
private void setLockTime(Long lockTime) {
LoginSessionUtil.lockTime = lockTime;
}
/**
* 校验用户登录失败次数
*
* @param session
* @param username
* @return
*/
public static boolean checkLock(HttpSession session, String username) {
Object o = session.getServletContext().getAttribute(username);
if (o == null) {
return true;
}
HashMap<String, Object> map = (HashMap<String, Object>) o;
int num = (int) map.get("num");
Date date = (Date) map.get("lastDate");
long timeDifference = ((new Date().getTime() - date.getTime()) / 60 / 1000);
if (num >= failNum && timeDifference < lockTime) {
return false;
}
return true;
}
/**
* 新增用户登录失败次数
*
* @param session
* @param username
*/
public static Integer addFailNum(HttpSession session, String username) {
Object o = session.getServletContext().getAttribute(username);
HashMap<String, Object> map = null;
int num = 0;
if (o == null) {
map = new HashMap<String, Object>();
} else {
map = (HashMap<String, Object>) o;
num = (int) map.get("num");
Date date = (Date) map.get("lastDate");
long timeDifference = ((new Date().getTime() - date.getTime()) / 60 / 1000);
if (timeDifference >= lockTime) {
num = 0;
}
}
map.put("num", num + 1);
map.put("lastDate", new Date());
session.getServletContext().setAttribute(username, map);
return num;
}
/**
* 清理用户登录失败的记录
*
* @param session
* @param username
*/
public static void cleanFailNum(HttpSession session, String username) {
session.getServletContext().removeAttribute(username);
}
/**
* 计算剩余登录次数
*
* @param isFailNum 当前失败次数
* @return
*/
public static String loginCount(Integer isFailNum) {
int i = LoginSessionUtil.failNum - isFailNum;
String resultStr = "";
if (lockTime != 0) {
if (lockTime / 60 == 0) {
resultStr += lockTime % 60 + "分钟";
} else {
if (lockTime % 60 == 0) {
resultStr += lockTime / 60 + "小时";
} else {
resultStr += (lockTime / 60 + "小时" + lockTime % 60 + "分钟");
}
}
} else {
resultStr += "0时0分钟";
}
return return i+"次用户名或密码错误后,账号将锁定"+resultStr;
}
/**
* 锁定时间计算
* @param session Session对象
* @param username 用户信息
* @return
*/
public static String lockTime(HttpSession session, String username) {
HashMap<String, Object> map = (HashMap<String, Object>) session.getServletContext().getAttribute(username);
Date date = (Date) map.get("lastDate");
//获取最后一次登录失败时间 计算解锁时间
long lockOutTime = LoginSessionUtil.lockTime - ((new Date().getTime() - date.getTime()) / 60 / 1000);
String resultStr = "账号已锁定,";
if (lockOutTime != 0) {
if (lockOutTime / 60 == 0) {
resultStr += lockOutTime % 60 + "分钟";
} else {
if (lockOutTime % 60 == 0) {
resultStr += lockOutTime / 60 + "小时";
} else {
resultStr += (lockOutTime / 60 + "小时" + lockOutTime % 60 + "分钟");
}
}
} else {
resultStr += "0时0分钟";
}
return resultStr += "后解锁";
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# 登录使用:
public Object login(String username,String password, HttpSession session){
//判断当前账号是否锁定
if(!LoginSessionUtil.checkLock(session, username)) {
//如果锁定操作 ...
//返回锁定时长
return Result.with(-1, LoginSessionUtil.lockTime(session,username));
}
//登录操作 ...
//登录成功清空登录失败次数
LoginSessionUtil.cleanFailNum(session, username);
//登录失败操作 ...
//在session中记录失败次数
Integer isFailNum = LoginSessionUtil.addFailNum(session, username) + 1;
//登录失败返回登录失败错误次数和剩余次数
return Result.with(-1, LoginSessionUtil.loginCount(isFailNum));
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Session登录失败限制,主要通过在session存储失败次数和最后登录时间来判断是否允许登录,来达到登录限制。
# RSA密码加密
RSAUtil: 公私钥分别保存在publicKey.properties和privateKey.properties中
RSAUtil 主要方法
/**
* 公钥加密
* @param str 需要加密的数据
* @throws Exception
*/
public static String publicKeyEncrypt(String str) throws Exception {
Resource publicKeyResource = new ClassPathResource("publicKey.properties");
Properties publicKeyProperties = new Properties();
publicKeyProperties.load(publicKeyResource.getInputStream());
String publicKey = publicKeyProperties.getProperty("publicKey");
//base64编码的公钥
byte[] decoded = Base64.getDecoder().decode(publicKey);
RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
//RSA加密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
String outStr = Base64.getEncoder().encodeToString(cipher.doFinal(str.getBytes("UTF-8")));
return outStr;
}
/**
* 私钥解密
* @param str 密文
* @return
* @throws Exception
*/
public static String privateKeyDecrypt(String str) throws Exception {
Resource privateKeyResource = new ClassPathResource("privateKey.properties");
Properties privateKeyProperties = new Properties();
privateKeyProperties.load(privateKeyResource.getInputStream());
String privateKey = privateKeyProperties.getProperty("privateKey");
//64位解码加密后的字符串
byte[] inputByte = Base64.getDecoder().decode(str);
//base64编码的私钥
byte[] decoded = Base64.getDecoder().decode(privateKey);
RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
//RSA解密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, priKey);
String outStr = new String(cipher.doFinal(inputByte));
return outStr;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
//登录时将前端加密后的密码进行解密
String decryptyPassword = RSAUtil.privateKeyDecrypt(password)
1
2
2
# 前端加密实现
//在src/util中新建rsa.js
//导入加密需要的库
import JSEncrypt from 'jsencrypt'
//公钥
const publicKey = 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjc257f5K/pJwqKBXpinDDJ3O4FIuYhgS4tQQzlpXin42i2f773WesOLcm7aKntJbK3mpetaaQwiTfPAqJD4wdFuue7JqKSZbkWXBOTTSobBkXTOTSlrWyOhk+eX+Q6LlMC7np749e5Oi3z/g8BQNMs5wFMgJdOwT/9mPsKZqC7gwVJnZsHqXxf6+sToC3BYHxelaXaSruGOSWPOexdBC5TjIjTWr5VbgVU90O97p9rQgOF/BOfbdNz3rftPHJ7gLmi6lYgbMmTFmZOwDojAZTNXwt9h3rEHOjO7pwc/wL4HqW44bhuRqZR8Kq7NaUSsXjWIdrfbOu7pJ9o0PuJcIEwIDAQAB'
export default {
/* JSEncrypt加密 */
encrypt(data) {
var jsencrypt = new JSEncrypt()
jsencrypt.setPublicKey(publicKey)
// 如果是对象/数组的话,需要先JSON.stringify转换成字符串
var result = jsencrypt.encrypt(data)
return result
},
/* JSEncrypt解密 */
decrypt(data) {
var jsencrypt = new JSEncrypt()
jsencrypt.setPrivateKey(privateKey)
// 如果是对象/数组的话,需要先JSON.stringify转换成字符串
var result = jsencrypt.encrypt(data)
return result
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//在main.js中导入rsa.js
import Rsa from "./utils/rsa.js"
//vue rsa.js挂载全局
Vue.prototype.Rsa = Rsa
1
2
3
4
2
3
4
//调用Rsa加密方法对密码进行加密 加密后赋值给传递后台的对象属性
this.Rsa.encrypt(this.loginForm.password)
1
2
2
上次更新: 2022/10/15, 15:19:25