REM:
1. 更新REST-ful根路径为x.x.x.x:????/dispose
2. 增加登录,注销功能实现
This commit is contained in:
huangxin 2020-04-09 18:20:02 +08:00
parent abf95684d4
commit 7930b85b94
25 changed files with 669 additions and 71 deletions

View File

@ -2,7 +2,7 @@ server.port=9276
# 根据自身环境修改
server.tomcat.basedir=./basedir
# 多个项目放在nginx下同个端口通过该配置区分
server.servlet.context-path=/phoenix
server.servlet.context-path=/dispose
# 配置数据源
spring.datasource.url=jdbc:mysql://172.28.72.118:33061/dispose?serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=convertToNull&useUnicode=true

View File

@ -1,6 +1,11 @@
package com.cmcc.hy.phoenix.common;
public class ConstValue {
public class GlobalConfigure {
public static final int TOKEN_TIMEOUT_MS = 30 * 60 * 1000;
public static final int ALLOW_PWD_ERR_TIMES = 5;
}
public class SOAPWrapperConst {
public static final String NAMESPACE_URI = "http://10.88.77.15/UMC/service/AbnormalFlowCleaningService";
public static final String SERVICE_ADDRESS = "http://10.88.77.15/UMC/service/AbnormalFlowCleaningService?wsdl";
@ -16,10 +21,20 @@ public class ConstValue {
public static final int CRYPTO_AES256 = 2;
}
public class ProtocolCmdId {
public static final int AUTH_LOGIN = 10;
public static final int AUTH_LOGOUT = 11;
}
public enum DisposeDevice {
DPTECH_UMC, HAOHAN_PLATFORM;
}
public class UserAccountStatus {
public static final int NORMAL = 0;
public static final int LOCKED = 1;
}
/**
* @brief 错误码常量定义
*/
@ -27,7 +42,7 @@ public class ConstValue {
ERR_OK (0, "成功"),
ERR_PASSWORD (1, "密码错误"),
ERR_USERNOTFOUND (2, "用户不存在"),
ERR_PASSWORDMORE (3, "连续密码错误达3次,再次输入错误将锁定用户"),
ERR_PASSWORDMORE (3, "连续密码错误达上限,再次输入错误将锁定用户"),
ERR_USERLOCK (4, "密码错误达上限,用户被锁定"),
ERR_ACCOUNT (5, "用户账户异常"),
ERR_USEREXIST (6, "该用户已经存在"),
@ -37,6 +52,11 @@ public class ConstValue {
ERR_PERMISSION (10, "操作员权限不足"),
ERR_REQTIMEOUT (11, "请求超时"),
ERR_PARAMS (12, "参数错误"),
ERR_EXCEPTION (13, "系统异常"),
ERR_UNKNOWNCMD (14, "未知命令"),
ERR_LOGOUT (15, "用户未登录"),
ERR_TOKENTIMEOUT (16, "Token超时"),
ERR_TOKENNOTFOUND (17, "非法Token"),
;
private int errno;
@ -51,6 +71,14 @@ public class ConstValue {
return errno;
}
public int getHttpCode() {
if(this.errno == 0) {
return 200;
} else {
return 500 + this.errno;
}
}
public String getMsg() {
return errMsg;
}

View File

@ -0,0 +1,23 @@
package com.cmcc.hy.phoenix.config;
import com.cmcc.hy.phoenix.pojo.po.UserAccountCache;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@Component
@Slf4j
public class SetupInit implements CommandLineRunner {
//@Resource
//private UserAccountCache userAccount;
@Override
public void run(String... args) throws Exception {
// TODO Auto-generated method stub
log.info("System Setup................................................");
//fileLoadService.mailFileRefresh();
}
}

View File

@ -0,0 +1,148 @@
package com.cmcc.hy.phoenix.controller;
import cn.hutool.core.convert.Convert;
import com.cmcc.hy.phoenix.annotation.bodyencdec.ReqDec;
import com.cmcc.hy.phoenix.common.ConstValue;
import com.cmcc.hy.phoenix.mapper.UserAccountMapper;
import com.cmcc.hy.phoenix.pojo.dto.ProtocolDTO;
import com.cmcc.hy.phoenix.pojo.entity.UserAccount;
import com.cmcc.hy.phoenix.pojo.vo.*;
import com.cmcc.hy.phoenix.service.LoginService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.Builder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Hex;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.MissingRequestHeaderException;
import org.springframework.web.bind.annotation.*;
import tk.mybatis.mapper.entity.Example;
import javax.annotation.Resource;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import static com.sun.corba.se.impl.util.RepositoryId.cache;
@Controller
@RequestMapping(value = "/handle")
@Slf4j
@Api(value = "抗DDoS处置平台认证接口", tags = "抗DDoS处置平台认证接口")
@Component
public class AuthController {
@Resource
private ObjectMapper objectMapper;
@Resource
private LoginService loginService;
@PostMapping("/login")
@ResponseBody
@ApiOperation("获取版本信息")
@ReqDec
@Builder
public ProtocolResp UserLogin(@RequestBody(required = true) ProtocolDTO mr,
@RequestHeader HttpHeaders headers) {
String msgCtx = "";
ConstValue.ErrorCode err = ConstValue.ErrorCode.ERR_OK;
log.info("请求token: {}", headers.get("Authorization"));
log.info("请求参数 {}", mr);
if(mr == null) {
err = ConstValue.ErrorCode.ERR_PARAMS;
return ProtocolResp.result(err, -1, msgCtx);
} else if (mr.IsRequestTimeout()) {
err = ConstValue.ErrorCode.ERR_REQTIMEOUT;
} else {
try {
if(mr.getCmdId() == ConstValue.ProtocolCmdId.AUTH_LOGIN) {
EnumMap<ConstValue.ErrorCode, String> loginMap = userLogin(mr);
err = loginMap.keySet().iterator().next();
msgCtx = loginMap.get(err);
} else if (mr.getCmdId() == ConstValue.ProtocolCmdId.AUTH_LOGOUT) {
if(headers.get("Authorization") == null
|| Objects.requireNonNull(headers.get("Authorization")).size() == 0) {
err = ConstValue.ErrorCode.ERR_LOGOUT;
} else {
EnumMap<ConstValue.ErrorCode, String> loginMap = userLogout(mr,
Objects.requireNonNull(headers.get("Authorization")).get(0));
err = loginMap.keySet().iterator().next();
msgCtx = loginMap.get(err);
}
}else {
err = ConstValue.ErrorCode.ERR_UNKNOWNCMD;
}
} catch (JsonProcessingException | NoSuchAlgorithmException ex) {
log.error(ex.getMessage());
err = ConstValue.ErrorCode.ERR_EXCEPTION;
}
}
return ProtocolResp.result(err, mr.getCmdId(), msgCtx);
}
private EnumMap<ConstValue.ErrorCode, String> userLogout(ProtocolDTO mr, String token)
throws JsonProcessingException {
EnumMap<ConstValue.ErrorCode, String> retMap = new EnumMap<>(ConstValue.ErrorCode.class);
ConstValue.ErrorCode err = ConstValue.ErrorCode.ERR_OK;
UserLogoutRsp rspInfo = UserLogoutRsp.builder()
.userName("")
.status(err.getCode())
.message(err.getMsg()).build();
UserLogoutReq reqInfo = objectMapper.readValue(mr.getMsgContent(), UserLogoutReq.class);
rspInfo.setUserName(reqInfo.getUserName());
err = loginService.logoutService(reqInfo.userName, token.replaceFirst("Bearer ", ""));
rspInfo.setStatus(err.getCode());
rspInfo.setMessage(err.getMsg());
retMap.put(err, objectMapper.writeValueAsString(rspInfo));
return retMap;
}
private EnumMap<ConstValue.ErrorCode, String> userLogin(ProtocolDTO mr)
throws NoSuchAlgorithmException, JsonProcessingException {
EnumMap<ConstValue.ErrorCode, String> retMap = new EnumMap<>(ConstValue.ErrorCode.class);
ConstValue.ErrorCode err = ConstValue.ErrorCode.ERR_OK;
UserLoginRsp rspInfo = UserLoginRsp.builder()
.userName("")
.token("")
.status(err.getCode())
.message(err.getMsg())
.expireTime(0L)
.logTime(System.currentTimeMillis()).build();
UserLoginReq reqInfo = objectMapper.readValue(mr.getMsgContent(), UserLoginReq.class);
rspInfo.setUserName(reqInfo.getUserName());
EnumMap<ConstValue.ErrorCode, String> logMap = loginService.loginService(reqInfo.getUserName(),
reqInfo.getPassword());
if(logMap.isEmpty()) {
err = ConstValue.ErrorCode.ERR_USERNOTFOUND;
} else {
err = logMap.keySet().iterator().next();
rspInfo.setToken(logMap.get(err));
}
rspInfo.setStatus(err.getCode());
rspInfo.setMessage(err.getMsg());
retMap.put(err, objectMapper.writeValueAsString(rspInfo));
return retMap;
}
}

View File

@ -0,0 +1,40 @@
package com.cmcc.hy.phoenix.controller;
import com.cmcc.hy.phoenix.annotation.bodyencdec.ReqDec;
import com.cmcc.hy.phoenix.common.ConstValue;
import com.cmcc.hy.phoenix.pojo.dto.ProtocolDTO;
import com.cmcc.hy.phoenix.pojo.vo.ProtocolResp;
import com.cmcc.hy.phoenix.service.UserAccountCacheService;
import com.fasterxml.jackson.core.JsonProcessingException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.Builder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@Controller
@RequestMapping(value = "/debug")
@Slf4j
@Api(value = "抗DDoS处置平台调试接口", tags = "抗DDoS处置平台调试接口")
@Component
public class DebugController {
@Resource
private UserAccountCacheService userAccountService;
@GetMapping("/cacheuser")
@ResponseBody
@ApiOperation("获取缓存用户")
@ReqDec
@Builder
public ProtocolResp UserLogin(@RequestBody(required = true) ProtocolDTO mr) throws JsonProcessingException {
return ProtocolResp.result(ConstValue.ErrorCode.ERR_OK, -1, userAccountService.getCacheUser());
}
}

View File

@ -6,8 +6,8 @@ import com.cmcc.hy.phoenix.common.ConstValue;
import com.cmcc.hy.phoenix.help.GitInformation;
import com.cmcc.hy.phoenix.pojo.dto.ProtocolDTO;
import com.cmcc.hy.phoenix.pojo.vo.Resp;
import com.cmcc.hy.phoenix.vo.GetVersion;
import com.cmcc.hy.phoenix.vo.ProtocolResp;
import com.cmcc.hy.phoenix.pojo.vo.GetVersion;
import com.cmcc.hy.phoenix.pojo.vo.ProtocolResp;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Builder;
@ -53,6 +53,8 @@ public class ProtocolController {
if(mr == null) {
return ProtocolResp.result(ConstValue.ErrorCode.ERR_PARAMS);
} else if (mr.IsRequestTimeout()) {
return ProtocolResp.result(ConstValue.ErrorCode.ERR_REQTIMEOUT);
}
try {

View File

@ -75,7 +75,7 @@ public class TestController {
@GetMapping("/mail")
@ResponseBody
public MyResp sendMail() {
asyncService.sendMail("这是邮件内容");
//asyncService.sendMail("这是邮件内容");
log.info("记住我的线程名 {},和实际发送的线程名不一样", Thread.currentThread().getName());
return MyResp.result(Resp.SUCCESS);
}

View File

@ -1,14 +1,20 @@
package com.cmcc.hy.phoenix.mapper;
import com.cmcc.hy.phoenix.pojo.entity.UserAccount;
import org.apache.ibatis.annotations.Param;
import tk.mybatis.mapper.common.IdsMapper;
import tk.mybatis.mapper.common.Mapper;
import tk.mybatis.mapper.common.MySqlMapper;
import java.sql.Timestamp;
import java.util.List;
public interface UserAccountMapper extends Mapper<UserAccount>,
IdsMapper<UserAccount>, MySqlMapper<UserAccount> {
List<UserAccount> getUserByName(String name);
UserAccount getUserByName(String username);
void lockUserAccount(@Param("username")String username);
void unlockUserAccount(@Param("username")String username);
void refreshLoginTime(@Param("username")String username);
}

View File

@ -47,13 +47,14 @@ public class ProtocolDTO {
private int code;
public Boolean IsRequestTimeout() {
Long timeDiff = System.currentTimeMillis() - this.timeStamp;
Long current = System.currentTimeMillis();
Long timeDiff = current - this.timeStamp;
if (timeDiff > 0 && timeDiff <= 3000) {
return true;
return false;
}
return true;
return false;
}
}

View File

@ -50,10 +50,6 @@ public class UserAccount implements Serializable {
*/
private String lastLoginTime;
/**
* 连续密码错误次数
*/
private Integer pwdErrTimes;
/**
* 账户锁定时间

View File

@ -0,0 +1,15 @@
package com.cmcc.hy.phoenix.pojo.po;
import lombok.*;
@Setter
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserAccountCache {
private String username;
private String token;
private Long lastAccess;
private Integer pwdErrTimes;
}

View File

@ -1,4 +1,4 @@
package com.cmcc.hy.phoenix.vo;
package com.cmcc.hy.phoenix.pojo.vo;
import lombok.Getter;
import lombok.Setter;
@ -15,8 +15,4 @@ public class GetVersion {
private String commit_time;
private String tag_name;
private String tags;
public static GetVersion result(String commit){
return GetVersion.builder().commit_id(commit).build();
}
}

View File

@ -1,7 +1,6 @@
package com.cmcc.hy.phoenix.vo;
package com.cmcc.hy.phoenix.pojo.vo;
import com.cmcc.hy.phoenix.common.ConstValue;
import com.cmcc.hy.phoenix.pojo.vo.Resp;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Getter;
@ -53,41 +52,26 @@ public class ProtocolResp {
}
public static ProtocolResp result(ConstValue.ErrorCode err) {
int code = Resp.SUCCESS.getCode();
if(err.getCode() != 0) {
code = 1000 + err.getCode();
}
return ProtocolResp.builder()
.ver(ConstValue.Protocol.VERSION)
.cryptoType(ConstValue.Protocol.CRYPTO_NONE)
.code(code)
.code(err.getHttpCode())
.timeStamp(System.currentTimeMillis())
.msgContent(err.getMsg()).build();
}
public static ProtocolResp result(ConstValue.ErrorCode err, Integer cmdId, String respMsg) {
int code = Resp.SUCCESS.getCode();
if(err.getCode() != 0) {
code = 1000 + err.getCode();
}
return result(err, cmdId, respMsg, ConstValue.Protocol.CRYPTO_NONE);
}
public static ProtocolResp result(ConstValue.ErrorCode err, Integer cmdId, String respMsg, Integer crypto) {
int code = Resp.SUCCESS.getCode();
if(err.getCode() != 0) {
code = 1000 + err.getCode();
}
return ProtocolResp.builder()
.cmdId(cmdId + ConstValue.Protocol.RESP_CMD_BASE)
.ver(ConstValue.Protocol.VERSION)
.cryptoType(crypto)
.code(code)
.timeStamp(System.currentTimeMillis())
.code(err.getHttpCode())
.msgContent(respMsg).build();
}
}

View File

@ -0,0 +1,11 @@
package com.cmcc.hy.phoenix.pojo.vo;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class UserLoginReq {
public String userName;
public String password;
}

View File

@ -0,0 +1,19 @@
package com.cmcc.hy.phoenix.pojo.vo;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@ToString
@Builder
public class UserLoginRsp {
private String userName;
private String token;
private Long logTime;
private Long expireTime;
private Integer status;
private String message;
}

View File

@ -0,0 +1,11 @@
package com.cmcc.hy.phoenix.pojo.vo;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class UserLogoutReq {
public String userName;
public String token;
}

View File

@ -0,0 +1,16 @@
package com.cmcc.hy.phoenix.pojo.vo;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@ToString
@Builder
public class UserLogoutRsp {
private String userName;
private Integer status;
private String message;
}

View File

@ -8,11 +8,6 @@ package com.cmcc.hy.phoenix.service;
*/
public interface AsyncService {
/**
*
* @Description: 发邮件测试
* @param cont
*/
public void sendMail(String cont);
}

View File

@ -0,0 +1,11 @@
package com.cmcc.hy.phoenix.service;
import com.cmcc.hy.phoenix.common.ConstValue;
import java.security.NoSuchAlgorithmException;
import java.util.EnumMap;
public interface LoginService {
public EnumMap<ConstValue.ErrorCode, String> loginService(String username, String password) throws NoSuchAlgorithmException;
public ConstValue.ErrorCode logoutService(String username, String token);
}

View File

@ -0,0 +1,16 @@
package com.cmcc.hy.phoenix.service;
import com.cmcc.hy.phoenix.common.ConstValue;
import com.fasterxml.jackson.core.JsonProcessingException;
import java.security.NoSuchAlgorithmException;
public interface UserAccountCacheService {
String getUserToken(String username) throws NoSuchAlgorithmException;
int getUsrPwdErrTimes(String username);
void setUserPwdErrTimes(String username, Integer errTimes);
void cleanUserToken(String username);
ConstValue.ErrorCode verifyUserLogin(String username, String token);
String getCacheUser() throws JsonProcessingException;
}

View File

@ -17,21 +17,6 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
public class AsyncServiceImpl implements AsyncService {
/**
* Async(xx) 表明用哪个线程池来完成异步任务对应ThreadPoolConfig中的线程池定义
*
* @see com.cmcc.hy.phoenix.service.AsyncService#sendMail(java.lang.String)
*/
@Async("bizExecutor")
@Override
public void sendMail(String cont) {
// TODO Auto-generated method stub
try {
Thread.sleep(5000);
log.info("异步发送邮件,邮件内容 " + cont);
} catch (Throwable e) {
log.error("发送邮件异常", e);
}
}
}

View File

@ -0,0 +1,87 @@
package com.cmcc.hy.phoenix.service.impl;
import com.cmcc.hy.phoenix.common.ConstValue;
import com.cmcc.hy.phoenix.mapper.UserAccountMapper;
import com.cmcc.hy.phoenix.pojo.entity.UserAccount;
import com.cmcc.hy.phoenix.service.LoginService;
import com.cmcc.hy.phoenix.service.UserAccountCacheService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.security.NoSuchAlgorithmException;
import java.util.EnumMap;
import java.util.List;
@Service
@Slf4j
public class LoginServiceImpl implements LoginService {
@Resource
private UserAccountCacheService userAccountService;
@Resource
private UserAccountMapper userAccountMapper;
@Override
public EnumMap<ConstValue.ErrorCode, String> loginService(String username, String password) throws NoSuchAlgorithmException {
EnumMap<ConstValue.ErrorCode, String> retMap = new EnumMap<>(ConstValue.ErrorCode.class);
// Example exp = new Example(UserAccount.class);
// exp.createCriteria().andEqualTo("username", username);
userAccountMapper.refreshLoginTime(username);
UserAccount loginUser = userAccountMapper.getUserByName(username);
// 用户为空
if(loginUser == null) {
retMap.put(ConstValue.ErrorCode.ERR_USERNOTFOUND, "");
} else {
if(loginUser.getStatus() == ConstValue.UserAccountStatus.LOCKED) {
retMap.put(ConstValue.ErrorCode.ERR_USERLOCK, "");
} else if(!loginUser.getPassword().equals(password)) {
// 密码错误
int errTimes = userAccountService.getUsrPwdErrTimes(username) + 1;
// 更新密码错误次数
userAccountService.setUserPwdErrTimes(username, errTimes);
if(errTimes == ConstValue.GlobalConfigure.ALLOW_PWD_ERR_TIMES - 1) {
// 提示用户即将锁定账户
retMap.put(ConstValue.ErrorCode.ERR_PASSWORDMORE, "");
} else if(errTimes >= ConstValue.GlobalConfigure.ALLOW_PWD_ERR_TIMES) {
// 锁定账户
retMap.put(ConstValue.ErrorCode.ERR_USERLOCK, "");
userAccountMapper.lockUserAccount(username);
} else {
retMap.put(ConstValue.ErrorCode.ERR_PASSWORD, "");
}
} else {
retMap.put(ConstValue.ErrorCode.ERR_OK, userAccountService.getUserToken(username));
userAccountService.setUserPwdErrTimes(username, 0);
}
}
return retMap;
}
@Override
public ConstValue.ErrorCode logoutService(String username, String token) {
ConstValue.ErrorCode err = ConstValue.ErrorCode.ERR_OK;
UserAccount loginUser = userAccountMapper.getUserByName(username);
// 用户为空
if(loginUser == null) {
err = ConstValue.ErrorCode.ERR_USERNOTFOUND;
} else {
err = userAccountService.verifyUserLogin(username, token);
if(err == ConstValue.ErrorCode.ERR_OK) {
userAccountService.cleanUserToken(username);
}
}
return err;
}
}

View File

@ -0,0 +1,137 @@
package com.cmcc.hy.phoenix.service.impl;
import cn.hutool.core.convert.Convert;
import com.cmcc.hy.phoenix.common.ConstValue;
import com.cmcc.hy.phoenix.pojo.po.UserAccountCache;
import com.cmcc.hy.phoenix.service.UserAccountCacheService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Hex;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
@Service
@Slf4j
public class UserAccountCacheServiceImpl implements UserAccountCacheService {
@Resource
private ObjectMapper objectMapper;
private ConcurrentHashMap<String, UserAccountCache> userAccountMap = new ConcurrentHashMap<>();
@Override
public ConstValue.ErrorCode verifyUserLogin(String username, String token) {
if(!userAccountMap.containsKey(username)) {
return ConstValue.ErrorCode.ERR_USERNOTFOUND;
}
UserAccountCache uc = userAccountMap.get(username);
if(uc.getToken().length() == 0) {
return ConstValue.ErrorCode.ERR_LOGOUT;
}
if((System.currentTimeMillis() - uc.getLastAccess())
>= ConstValue.GlobalConfigure.TOKEN_TIMEOUT_MS)
{
return ConstValue.ErrorCode.ERR_TOKENTIMEOUT;
}
if(!uc.getToken().equals(token)) {
return ConstValue.ErrorCode.ERR_TOKENNOTFOUND;
}
return ConstValue.ErrorCode.ERR_OK;
}
@Override
public String getCacheUser() throws JsonProcessingException {
return objectMapper.writeValueAsString(userAccountMap);
}
@Override
public void cleanUserToken(String username) {
if(userAccountMap.containsKey(username)) {
UserAccountCache uc = userAccountMap.get(username);
uc.setToken("");
}
}
@Override
public int getUsrPwdErrTimes(String username) {
if(userAccountMap.containsKey(username)) {
UserAccountCache uc = userAccountMap.get(username);
return uc.getPwdErrTimes();
} else {
UserAccountCache uc = UserAccountCache.builder()
.username(username)
.token("")
.lastAccess(System.currentTimeMillis())
.pwdErrTimes(0)
.lastAccess(System.currentTimeMillis()).build();
userAccountMap.put(username, uc);
return 0;
}
}
@Override
public void setUserPwdErrTimes(String username, Integer errTimes) {
if(userAccountMap.containsKey(username)) {
UserAccountCache uc = userAccountMap.get(username);
uc.setPwdErrTimes(Math.abs(errTimes));
}
}
@Override
public String getUserToken(String username) throws NoSuchAlgorithmException {
if(userAccountMap.containsKey(username)) {
UserAccountCache uc = userAccountMap.get(username);
if((System.currentTimeMillis() - uc.getLastAccess())
>= ConstValue.GlobalConfigure.TOKEN_TIMEOUT_MS
|| uc.getToken().length() == 0) {
uc.setToken(createUserToken(username));
log.info("Refresh {} Token:{}", username, uc.getToken());
} else {
log.info("Get {} Token:{}", username, uc.getToken());
}
uc.setLastAccess(System.currentTimeMillis());
return uc.getToken();
} else {
UserAccountCache uc = UserAccountCache.builder()
.username(username)
.token(createUserToken(username))
.lastAccess(System.currentTimeMillis())
.pwdErrTimes(0)
.lastAccess(System.currentTimeMillis()).build();
userAccountMap.put(username, uc);
log.info("Create {} Token:{}", username, uc.getToken());
return uc.getToken();
}
}
private String createUserToken(String username) throws NoSuchAlgorithmException {
// 获取指定摘要算法的messageDigest对象
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256"); // 此处的sha代表sha1
String tokenKey = username +
Convert.toStr(new Random(System.currentTimeMillis()).nextInt()) +
Convert.toStr(System.currentTimeMillis());
// 调用digest方法进行加密操作
byte[] cipherBytes = messageDigest.digest(tokenKey.getBytes());
return Hex.encodeHexString(cipherBytes);
}
}

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cmcc.hy.phoenix.mapper.UserAccountMapper">
<!-- mapper xml文件中只编写复杂逻辑的SQL SQL单独拿出来写与代码解耦SQL的熟练编写是每个研发必备的技能 -->
<select id="getUserByName" resultType="com.cmcc.hy.phoenix.pojo.entity.UserAccount">
SELECT * FROM user_account WHERE username = #{username}
</select>
<update id="lockUserAccount">
UPDATE
user_account
SET
status = 1,
lockTime = CURRENT_TIMESTAMP
WHERE
username = #{username, jdbcType=VARCHAR}
</update>
<update id="unlockUserAccount">
UPDATE
user_account
SET
status = 0,
lockTime = 0
WHERE
username = #{username, jdbcType=VARCHAR}
</update>
<update id="refreshLoginTime">
UPDATE
user_account
SET
lastLoginTime = CURRENT_TIMESTAMP
WHERE
username = #{username, jdbcType=VARCHAR}
</update>
</mapper>

View File

@ -1,5 +1,6 @@
package com.cmcc.hy.phoenix.mapper;
import com.cmcc.hy.phoenix.common.ConstValue;
import com.cmcc.hy.phoenix.pojo.entity.UserAccount;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
@ -27,7 +28,7 @@ public class UserAccountMapperTest {
private UserAccountMapper userAccountMapper;
@Test
public void getUserByName() throws JsonProcessingException {
public void getUserByNameUsedDefaultMapper() throws JsonProcessingException {
Example exp = new Example(UserAccount.class);
exp.createCriteria().andEqualTo("username", "admin");
@ -38,4 +39,40 @@ public class UserAccountMapperTest {
Assert.assertEquals(users.size(), 1);
}
@Test
public void getUserByName() throws JsonProcessingException {
UserAccount user = userAccountMapper.getUserByName("admin");
log.info(objMapper.writerWithDefaultPrettyPrinter().writeValueAsString(user));
Assert.assertNotNull(user);
}
@Test
public void lockUser() throws JsonProcessingException {
userAccountMapper.lockUserAccount("admin");
UserAccount user = userAccountMapper.getUserByName("admin");
Assert.assertEquals(new Long(user.getStatus()), new Long(ConstValue.UserAccountStatus.LOCKED));
log.info(objMapper.writerWithDefaultPrettyPrinter().writeValueAsString(user));
}
@Test
public void unlockUser() throws JsonProcessingException {
userAccountMapper.unlockUserAccount("admin");
UserAccount user = userAccountMapper.getUserByName("admin");
Assert.assertEquals(new Long(user.getStatus()), new Long(ConstValue.UserAccountStatus.NORMAL));
log.info(objMapper.writerWithDefaultPrettyPrinter().writeValueAsString(user));
}
@Test
public void refreshLoginTime() throws JsonProcessingException {
userAccountMapper.refreshLoginTime("admin");
UserAccount user = userAccountMapper.getUserByName("admin");
Assert.assertNotNull(user);
log.info(objMapper.writerWithDefaultPrettyPrinter().writeValueAsString(user));
}
}