mirror of
https://gitee.com/dromara/Jpom.git
synced 2024-12-02 03:48:05 +08:00
fix user server
This commit is contained in:
parent
29f8cc9503
commit
4b6a03191a
1
PLANS.md
1
PLANS.md
@ -17,6 +17,7 @@
|
||||
11. ~~节点大屏~~
|
||||
12. ~~实时阅读日志文件~~
|
||||
13. ~~配置分发~~
|
||||
14. 修改数据库密码
|
||||
|
||||
# 2.7.x
|
||||
|
||||
|
@ -168,17 +168,18 @@ public class LoginControl extends BaseServerController {
|
||||
String sCode = getSessionAttribute(LOGIN_CODE);
|
||||
Assert.state(StrUtil.equalsIgnoreCase(code, sCode), "请输入正确的验证码");
|
||||
removeSessionAttribute(LOGIN_CODE);
|
||||
UserModel updateModel = null;
|
||||
try {
|
||||
long lockTime = userModel.overLockTime();
|
||||
if (lockTime > 0) {
|
||||
String msg = DateUtil.formatBetween(lockTime * 1000, BetweenFormatter.Level.SECOND);
|
||||
userModel.errorLock();
|
||||
updateModel = userModel.errorLock();
|
||||
this.ipError();
|
||||
return JsonMessage.getString(400, "该账户登录失败次数过多,已被锁定" + msg + ",请不要再次尝试");
|
||||
}
|
||||
// 验证
|
||||
if (userService.simpleLogin(userName, userPwd) != null) {
|
||||
userModel.unLock();
|
||||
updateModel = userModel.unLock();
|
||||
// 判断工作空间
|
||||
List<WorkspaceModel> bindWorkspaceModels = userBindWorkspaceService.listUserWorkspaceInfo(userModel);
|
||||
Assert.notEmpty(bindWorkspaceModels, "当前账号没有绑定任何工作空间,请联系管理员处理");
|
||||
@ -189,12 +190,14 @@ public class LoginControl extends BaseServerController {
|
||||
userLoginDto.setBindWorkspaceModels(bindWorkspaceModels);
|
||||
return JsonMessage.getString(200, "登录成功", userLoginDto);
|
||||
} else {
|
||||
userModel.errorLock();
|
||||
updateModel = userModel.errorLock();
|
||||
this.ipError();
|
||||
return JsonMessage.getString(501, "登录失败,请输入正确的密码和账号,多次失败将锁定账号");
|
||||
}
|
||||
} finally {
|
||||
userService.update(userModel);
|
||||
if (updateModel != null) {
|
||||
userService.update(updateModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -213,8 +213,7 @@ public class UserListController extends BaseServerController {
|
||||
public String unlock(String id) {
|
||||
UserModel userModel = userService.getByKey(id);
|
||||
Assert.notNull(userModel, "修改失败:-1");
|
||||
userModel.unLock();
|
||||
userService.update(userModel);
|
||||
userService.update(userModel.unLock());
|
||||
return JsonMessage.getString(200, "解锁成功");
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,8 @@ import cn.hutool.core.util.StrUtil;
|
||||
import io.jpom.model.BaseStrikeDbModel;
|
||||
import io.jpom.service.h2db.TableName;
|
||||
import io.jpom.system.ServerExtConfigBean;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@ -37,7 +39,9 @@ import java.util.concurrent.TimeUnit;
|
||||
* @author jiangzeyin
|
||||
* @date 2019/1/16
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName(value = "USER_INFO", name = "用户账号")
|
||||
@Data
|
||||
public class UserModel extends BaseStrikeDbModel {
|
||||
/**
|
||||
* 系统管理员
|
||||
@ -71,7 +75,14 @@ public class UserModel extends BaseStrikeDbModel {
|
||||
* 密码
|
||||
*/
|
||||
private String password;
|
||||
/**
|
||||
* 密码盐值
|
||||
*/
|
||||
private String salt;
|
||||
/**
|
||||
* 两步验证 key
|
||||
*/
|
||||
private String twoFactorAuthKey;
|
||||
/**
|
||||
* 创建此用户的人
|
||||
*/
|
||||
@ -112,85 +123,26 @@ public class UserModel extends BaseStrikeDbModel {
|
||||
public UserModel() {
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getSalt() {
|
||||
return salt;
|
||||
}
|
||||
|
||||
public void setSalt(String salt) {
|
||||
this.salt = salt;
|
||||
}
|
||||
|
||||
public Integer getSystemUser() {
|
||||
return systemUser;
|
||||
}
|
||||
|
||||
public void setSystemUser(Integer systemUser) {
|
||||
this.systemUser = ObjectUtil.defaultIfNull(systemUser, 0) == 1 ? systemUser : 0;
|
||||
}
|
||||
|
||||
public Long getLockTime() {
|
||||
return lockTime;
|
||||
}
|
||||
|
||||
public Long getLastPwdErrorTime() {
|
||||
return lastPwdErrorTime;
|
||||
}
|
||||
|
||||
public void setLastPwdErrorTime(Long lastPwdErrorTime) {
|
||||
this.lastPwdErrorTime = lastPwdErrorTime;
|
||||
}
|
||||
|
||||
public void setLockTime(long lockTime) {
|
||||
this.lockTime = lockTime;
|
||||
}
|
||||
|
||||
public Integer getPwdErrorCount() {
|
||||
return pwdErrorCount;
|
||||
}
|
||||
|
||||
public void setPwdErrorCount(int pwdErrorCount) {
|
||||
this.pwdErrorCount = pwdErrorCount;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getDingDing() {
|
||||
return dingDing;
|
||||
}
|
||||
|
||||
public void setDingDing(String dingDing) {
|
||||
this.dingDing = dingDing;
|
||||
}
|
||||
|
||||
public String getWorkWx() {
|
||||
return workWx;
|
||||
}
|
||||
|
||||
public void setWorkWx(String workWx) {
|
||||
this.workWx = workWx;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解锁
|
||||
*/
|
||||
public void unLock() {
|
||||
setPwdErrorCount(0);
|
||||
setLockTime(0);
|
||||
setLastPwdErrorTime(0L);
|
||||
public UserModel unLock() {
|
||||
UserModel newModel = new UserModel(this.getId());
|
||||
return UserModel.unLock(newModel);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解锁
|
||||
*/
|
||||
public static UserModel unLock(UserModel newModel) {
|
||||
newModel.setPwdErrorCount(0);
|
||||
newModel.setLockTime(0L);
|
||||
newModel.setLastPwdErrorTime(0L);
|
||||
return newModel;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -230,53 +182,37 @@ public class UserModel extends BaseStrikeDbModel {
|
||||
/**
|
||||
* 登录失败,重新计算锁定时间
|
||||
*/
|
||||
public void errorLock() {
|
||||
public UserModel errorLock() {
|
||||
// 未开启锁定功能
|
||||
int userAlwaysLoginError = ServerExtConfigBean.getInstance().userAlwaysLoginError;
|
||||
if (userAlwaysLoginError <= 0) {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
setPwdErrorCount(getPwdErrorCount() + 1);
|
||||
int count = getPwdErrorCount();
|
||||
UserModel newModel = new UserModel(this.getId());
|
||||
newModel.setPwdErrorCount(ObjectUtil.defaultIfNull(this.getPwdErrorCount(), 0) + 1);
|
||||
int count = newModel.getPwdErrorCount();
|
||||
// 记录错误时间
|
||||
setLastPwdErrorTime(DateUtil.currentSeconds());
|
||||
newModel.setLastPwdErrorTime(DateUtil.currentSeconds());
|
||||
if (count < userAlwaysLoginError) {
|
||||
// 还未达到锁定条件
|
||||
return;
|
||||
return newModel;
|
||||
}
|
||||
int level = count / userAlwaysLoginError;
|
||||
switch (level) {
|
||||
case 1:
|
||||
// 在错误倍数 为1 锁定 30分钟
|
||||
setLockTime(TimeUnit.MINUTES.toSeconds(30));
|
||||
newModel.setLockTime(TimeUnit.MINUTES.toSeconds(30));
|
||||
break;
|
||||
case 2:
|
||||
// 在错误倍数 为2 锁定 1小时
|
||||
setLockTime(TimeUnit.HOURS.toSeconds(1));
|
||||
newModel.setLockTime(TimeUnit.HOURS.toSeconds(1));
|
||||
break;
|
||||
default:
|
||||
// 其他情况 10小时
|
||||
setLockTime(TimeUnit.HOURS.toSeconds(10));
|
||||
newModel.setLockTime(TimeUnit.HOURS.toSeconds(10));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public String getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public void setParent(String parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
// 记录修改时间,如果在线用户线退出
|
||||
//this.setModifyTime(DateUtil.current());
|
||||
return newModel;
|
||||
}
|
||||
|
||||
public boolean isSystemUser() {
|
||||
|
@ -107,18 +107,6 @@ public class UserService extends BaseDbService<UserModel> {
|
||||
return password;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否返回系统管理员信息
|
||||
*
|
||||
* @param hiddenSystem 隐藏系统管理员
|
||||
* @return list
|
||||
*/
|
||||
public List<UserModel> list(boolean hiddenSystem) {
|
||||
UserModel userModel = new UserModel();
|
||||
userModel.setSystemUser(hiddenSystem ? 0 : 1);
|
||||
return super.listByBean(userModel);
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前系统中的系统管理员的数量
|
||||
*
|
||||
@ -142,7 +130,7 @@ public class UserService extends BaseDbService<UserModel> {
|
||||
userModel.setId(id);
|
||||
userModel.setSalt(salt);
|
||||
userModel.setPassword(SecureUtil.sha1(newPwd + salt));
|
||||
userModel.unLock();
|
||||
UserModel.unLock(userModel);
|
||||
super.update(userModel);
|
||||
}
|
||||
|
||||
|
@ -7,12 +7,10 @@ package io.jpom.util;
|
||||
import cn.hutool.core.codec.Base32;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.crypto.SecureUtil;
|
||||
import cn.hutool.crypto.digest.HMac;
|
||||
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class TwoFactorAuthUtils {
|
||||
|
||||
private static final int VALID_TFA_WINDOW_MILLIS = 60_000;
|
||||
@ -34,11 +32,7 @@ public class TwoFactorAuthUtils {
|
||||
* @return 两步验证码
|
||||
*/
|
||||
public static String generateTFACode(String tfaKey) {
|
||||
try {
|
||||
return TimeBasedOneTimePasswordUtil.generateCurrentNumberString(tfaKey);
|
||||
} catch (GeneralSecurityException e) {
|
||||
throw new RuntimeException("两步验证码生成异常");
|
||||
}
|
||||
return TimeBasedOneTimePasswordUtil.generateCurrentNumberString(tfaKey);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -65,15 +59,8 @@ public class TwoFactorAuthUtils {
|
||||
|
||||
private static class TimeBasedOneTimePasswordUtil {
|
||||
public static final int DEFAULT_TIME_STEP_SECONDS = 30;
|
||||
private static final String BLOCK_OF_ZEROS;
|
||||
private static final int NUM_DIGITS_OUTPUT = 6;
|
||||
|
||||
static {
|
||||
char[] chars = new char[NUM_DIGITS_OUTPUT];
|
||||
Arrays.fill(chars, '0');
|
||||
BLOCK_OF_ZEROS = new String(chars);
|
||||
}
|
||||
|
||||
public static String generateBase32Secret(int length) {
|
||||
return RandomUtil.randomString(RandomUtil.BASE_CHAR, length).toUpperCase();
|
||||
}
|
||||
@ -104,15 +91,14 @@ public class TwoFactorAuthUtils {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static String generateCurrentNumberString(String base32Secret)
|
||||
throws GeneralSecurityException {
|
||||
return generateNumberString(base32Secret, System.currentTimeMillis(),
|
||||
DEFAULT_TIME_STEP_SECONDS);
|
||||
public static String generateCurrentNumberString(String base32Secret) {
|
||||
return generateNumberString(base32Secret, System.currentTimeMillis(), DEFAULT_TIME_STEP_SECONDS);
|
||||
}
|
||||
|
||||
public static String generateNumberString(String base32Secret, long timeMillis, int timeStepSeconds) {
|
||||
int number = generateNumber(base32Secret, timeMillis, timeStepSeconds);
|
||||
return zeroPrepend(number);
|
||||
String numStr = Integer.toString(number);
|
||||
return StrUtil.fillBefore(numStr, '0', TimeBasedOneTimePasswordUtil.NUM_DIGITS_OUTPUT);
|
||||
}
|
||||
|
||||
public static int generateNumber(String base32Secret, long timeMillis, int timeStepSeconds) {
|
||||
@ -151,18 +137,5 @@ public class TwoFactorAuthUtils {
|
||||
// addOtpAuthPart(keyId, secret, sb);
|
||||
return "otpauth://totp/" + keyId + "?secret=" + secret;
|
||||
}
|
||||
|
||||
static String zeroPrepend(int num) {
|
||||
String numStr = Integer.toString(num);
|
||||
if (numStr.length() >= TimeBasedOneTimePasswordUtil.NUM_DIGITS_OUTPUT) {
|
||||
return numStr;
|
||||
} else {
|
||||
StringBuilder sb = new StringBuilder(TimeBasedOneTimePasswordUtil.NUM_DIGITS_OUTPUT);
|
||||
int zeroCount = TimeBasedOneTimePasswordUtil.NUM_DIGITS_OUTPUT - numStr.length();
|
||||
sb.append(BLOCK_OF_ZEROS, 0, zeroCount);
|
||||
sb.append(numStr);
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,10 +15,11 @@ public class TwoFactorAuthTest {
|
||||
public void test() {
|
||||
String tfaKey = TwoFactorAuthUtils.generateTFAKey();
|
||||
System.out.println(tfaKey);
|
||||
String tfaCode = TwoFactorAuthUtils.generateTFACode(tfaKey);
|
||||
String generateOtpAuthUrl = TwoFactorAuthUtils.generateOtpAuthUrl("adin", tfaKey);
|
||||
String generateOtpAuthUrl = TwoFactorAuthUtils.generateOtpAuthUrl("jpom@jpom.com", tfaKey);
|
||||
System.out.println(generateOtpAuthUrl);
|
||||
|
||||
String tfaCode = TwoFactorAuthUtils.generateTFACode(tfaKey);
|
||||
|
||||
boolean validateTFACode = TwoFactorAuthUtils.validateTFACode(tfaKey, tfaCode);
|
||||
System.out.println(tfaCode);
|
||||
Assert.state(validateTFACode, "验证失败");
|
||||
|
@ -48,3 +48,8 @@ ALTER TABLE MONITOR_INFO
|
||||
|
||||
ALTER TABLE USER_BIND_WORKSPACE
|
||||
ALTER COLUMN workspaceId VARCHAR(100) comment '工作空间ID';
|
||||
|
||||
ALTER TABLE USER_INFO
|
||||
ALTER COLUMN twoFactorAuthKey VARCHAR(100) comment '两步验证';
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user