fix user server

This commit is contained in:
bwcx_jzy 2022-01-27 19:05:57 +08:00
parent 29f8cc9503
commit 4b6a03191a
No known key found for this signature in database
GPG Key ID: 5E48E9372088B9E5
8 changed files with 59 additions and 153 deletions

View File

@ -17,6 +17,7 @@
11. ~~节点大屏~~
12. ~~实时阅读日志文件~~
13. ~~配置分发~~
14. 修改数据库密码
# 2.7.x

View File

@ -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);
}
}
}
}

View File

@ -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, "解锁成功");
}

View File

@ -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() {

View File

@ -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);
}

View File

@ -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();
}
}
}
}

View File

@ -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, "验证失败");

View File

@ -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 '两步验证';