Commit 6e56921d authored by zengtianlai3's avatar zengtianlai3

解决安全策略设置不足-账号密码暴力破解

parent f8633e15
...@@ -17,6 +17,7 @@ import org.springframework.util.DigestUtils; ...@@ -17,6 +17,7 @@ import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore; import springfox.documentation.annotations.ApiIgnore;
import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
...@@ -53,25 +54,50 @@ public class LoginController { ...@@ -53,25 +54,50 @@ public class LoginController {
String account = dbUser.getUserName(); String account = dbUser.getUserName();
String psw = account + dbUser.getPassword(); String psw = account + dbUser.getPassword();
if (DigestUtils.md5DigestAsHex(account.getBytes()).equals(userName) && DigestUtils.md5DigestAsHex(psw.getBytes()).equals(password)) { if (DigestUtils.md5DigestAsHex(account.getBytes()).equals(userName) && DigestUtils.md5DigestAsHex(psw.getBytes()).equals(password)) {
log.info("登录成功!生成token!"); // 登录错误次数
String token = JwtUtil.createToken(dbUser); Integer errCnt = UserUtils.getErrCnt(userName);
LoginVo loginVo = new LoginVo(); Date countFreezeDate = UserUtils.getCountFreezeDate(userName);
loginVo.setAuthorization(token); Date curDate = new Date();
UserUtils.setToken(dbUser.getUserId(),token); if (errCnt != null && errCnt >= 3 && countFreezeDate != null && curDate.before(countFreezeDate)) {
UserUtils.setTokenExp(dbUser.getUserId(), JwtUtil.getTokenExp()); return ResResult.failed().setMsgValue("用户名或密码错误次数达到三次,请三分钟后再重试");
return ResResult.success().goRecord(loginVo); } else {
String token = JwtUtil.createToken(dbUser);
LoginVo loginVo = new LoginVo();
loginVo.setAuthorization(token);
UserUtils.setToken(dbUser.getUserId(),token);
UserUtils.setTokenExp(dbUser.getUserId(), JwtUtil.getTokenExp());
UserUtils.removeErrCnt(userName);
UserUtils.removeCountFreezeDate(userName);
log.info("登录成功!生成token!");
return ResResult.success().goRecord(loginVo);
}
}
}
Integer errCnt = UserUtils.getErrCnt(userName);
if (errCnt == null) {
UserUtils.setErrCnt(userName, 1);
} else {
if (errCnt == 1) {
UserUtils.setErrCnt(userName, ++errCnt);
} else if (errCnt == 2) {
UserUtils.setErrCnt(userName, ++errCnt);
Date freezeDate = new Date(System.currentTimeMillis() + 3 * 60 * 1000);
UserUtils.setCountFreezeDate(userName, freezeDate);
} else {
Date countFreezeDate = UserUtils.getCountFreezeDate(userName);
Date curDate = new Date();
if (curDate.before(countFreezeDate)) {
return ResResult.failed().setMsgValue("用户名或密码错误次数达到三次,请三分钟后再重试");
} else {
UserUtils.setErrCnt(userName, 1);
Date freezeDate = new Date(System.currentTimeMillis() + 3 * 60 * 1000);
UserUtils.setCountFreezeDate(userName, freezeDate);
}
} }
} }
return ResResult.failed().setMsgValue("用户名或密码错误"); return ResResult.failed().setMsgValue("用户名或密码错误");
} }
public static void main(String[] args) {
String account = "root";
String password = "root123456";
System.out.println(DigestUtils.md5DigestAsHex(account.getBytes()));
System.out.println(DigestUtils.md5DigestAsHex(password.getBytes()));
}
@ApiOperation(value = "注销接口", notes = "注销接口") @ApiOperation(value = "注销接口", notes = "注销接口")
@GetMapping("logout") @GetMapping("logout")
@MyLog(title = "注销", businessType = BusinessType.OTHER) @MyLog(title = "注销", businessType = BusinessType.OTHER)
......
...@@ -12,12 +12,15 @@ public abstract class UserUtils { ...@@ -12,12 +12,15 @@ public abstract class UserUtils {
static Map<String, String> tokenMap = new HashMap<>(); static Map<String, String> tokenMap = new HashMap<>();
static Map<String, Date> tokenExpTimeMap = new HashMap<>(); static Map<String, Date> tokenExpTimeMap = new HashMap<>();
//线程变量,存放user实体类信息,即使是静态的与其他线程也是隔离的 static Map<String, Integer> errCntMap = new HashMap<>();
static Map<String, Date> countFreezeDateMap = new HashMap<>();
/**
* 线程变量,存放user实体类信息,即使是静态的也与其他线程也是隔离的
*/
private static ThreadLocal<LoginUser> userThreadLocal = new ThreadLocal<>(); private static ThreadLocal<LoginUser> userThreadLocal = new ThreadLocal<>();
//线程变量,存放uri,即使是静态的与其他线程也是隔离的
private static ThreadLocal<String> uriThreadLocal = new ThreadLocal<>(); private static ThreadLocal<String> uriThreadLocal = new ThreadLocal<>();
//从当前线程变量中获取用户信息
public static LoginUser getLoginUser() { public static LoginUser getLoginUser() {
LoginUser user = userThreadLocal.get(); LoginUser user = userThreadLocal.get();
return user; return user;
...@@ -37,44 +40,31 @@ public abstract class UserUtils { ...@@ -37,44 +40,31 @@ public abstract class UserUtils {
return null; return null;
} }
//为当前的线程变量赋值上用户信息
public static void setLoginUser(LoginUser user) { public static void setLoginUser(LoginUser user) {
userThreadLocal.set(user); userThreadLocal.set(user);
} }
//清除userThreadLocal线程变量
public static void removeUser() { public static void removeUser() {
userThreadLocal.remove(); userThreadLocal.remove();
} }
//为当前的线程变量赋值上uri信息
public static void setUri(String uri) { public static void setUri(String uri) {
uriThreadLocal.set(uri); uriThreadLocal.set(uri);
} }
/**
* 获取当前访问方法的uri
* @return
*/
public static String getUri() { public static String getUri() {
String uri = uriThreadLocal.get(); String uri = uriThreadLocal.get();
return uri; return uri;
} }
//清除uriThreadLocal线程变量
public static void removeUri() { public static void removeUri() {
uriThreadLocal.remove(); uriThreadLocal.remove();
} }
//为当前的线程变量赋值上token信息
public static void setToken(String uId, String token) { public static void setToken(String uId, String token) {
tokenMap.put(uId, token); tokenMap.put(uId, token);
} }
/**
* 获取当前访问方法的token
* @return
*/
public static String getToken(String uId) { public static String getToken(String uId) {
System.out.println("---"); System.out.println("---");
String s = tokenMap.get(uId); String s = tokenMap.get(uId);
...@@ -82,27 +72,44 @@ public abstract class UserUtils { ...@@ -82,27 +72,44 @@ public abstract class UserUtils {
return tokenMap.get(uId); return tokenMap.get(uId);
} }
//清除tokenThreadLocal线程变量
public static void removeToken(String uId) { public static void removeToken(String uId) {
tokenMap.remove(uId); tokenMap.remove(uId);
} }
//为当前的线程变量赋值上token信息
public static void setTokenExp(String uId, Date tokenExpTime) { public static void setTokenExp(String uId, Date tokenExpTime) {
tokenExpTimeMap.put(uId, tokenExpTime); tokenExpTimeMap.put(uId, tokenExpTime);
} }
/**
* 获取当前访问方法的token
* @return
*/
public static Date getTokenExp(String uId) { public static Date getTokenExp(String uId) {
return tokenExpTimeMap.get(uId); return tokenExpTimeMap.get(uId);
} }
//清除tokenThreadLocal线程变量
public static void removeTokenExp(String uId) { public static void removeTokenExp(String uId) {
tokenExpTimeMap.remove(uId); tokenExpTimeMap.remove(uId);
} }
public static void setErrCnt(String uId, Integer count) {
errCntMap.put(uId, count);
}
public static Integer getErrCnt(String uId) {
return errCntMap.get(uId);
}
public static void removeErrCnt(String uId) {
errCntMap.remove(uId);
}
public static void setCountFreezeDate(String uId, Date freezeDate) {
countFreezeDateMap.put(uId, freezeDate);
}
public static Date getCountFreezeDate(String uId) {
return countFreezeDateMap.get(uId);
}
public static void removeCountFreezeDate(String uId) {
countFreezeDateMap.remove(uId);
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment