Commit d2d3afe0 authored by zengtianlai3's avatar zengtianlai3

修改多因子认证

parent 914a09b3
......@@ -144,6 +144,12 @@
<version>1.9</version>
</dependency>
<!--邮件-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>com.sixiang.iot</groupId>
<artifactId>server-license</artifactId>
......
......@@ -12,11 +12,16 @@ import iot.sixiang.license.log.MyLog;
import iot.sixiang.license.model.BaseResult;
import iot.sixiang.license.model.ResResult;
import iot.sixiang.license.model.vo.LoginVo;
import iot.sixiang.license.util.CommonUtil;
import iot.sixiang.license.util.EmailUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;
import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
......@@ -30,6 +35,12 @@ import java.util.Map;
@Api(value = "登录模块", tags = {"登录模块"})
public class LoginController {
@Resource
EmailUtils emailUtils;
@Value("${spring.mail.to}")
private String account;
//模拟数据库
static Map<String, LoginUser> userMap = new HashMap<>();
......@@ -43,17 +54,20 @@ public class LoginController {
*/
@ApiOperation(value = "登录接口", notes = "登录接口")
@GetMapping("login")
@MyLog(title = "登录", optParam = "#{userName},#{password}", businessType = BusinessType.OTHER)
@MyLog(title = "登录", optParam = "#{userName},#{password},#{code}", businessType = BusinessType.OTHER)
@ApiImplicitParams({
@ApiImplicitParam(name = "userName", value = "用户名", required = true),
@ApiImplicitParam(name = "password", value = "密码", required = true)
@ApiImplicitParam(name = "password", value = "密码", required = true),
@ApiImplicitParam(name = "code", value = "验证码", required = true)
})
public ResResult<LoginVo> login(@RequestParam("userName") String userName, @RequestParam("password") String password) {
public ResResult<LoginVo> login(@RequestParam("userName") String userName, @RequestParam("password") String password, @RequestParam("code") String code) {
if (StringUtils.isEmpty(userName) || StringUtils.isEmpty(password) || StringUtils.isEmpty(code)) {
return ResResult.validate_failed().setMsgValue("参数不能为空");
}
for (LoginUser dbUser : userMap.values()) {
String account = dbUser.getUserName();
String psw = account + dbUser.getPassword();
if (DigestUtils.md5DigestAsHex(account.getBytes()).equals(userName) && DigestUtils.md5DigestAsHex(psw.getBytes()).equals(password)) {
String name = dbUser.getUserName();
String psw = name + dbUser.getPassword();
if (DigestUtils.md5DigestAsHex(name.getBytes()).equals(userName) && DigestUtils.md5DigestAsHex(psw.getBytes()).equals(password)) {
// 登录错误次数
Integer errCnt = UserUtils.getErrCnt(userName);
Date countFreezeDate = UserUtils.getCountFreezeDate(userName);
......@@ -61,15 +75,22 @@ public class LoginController {
if (errCnt != null && errCnt >= 3 && countFreezeDate != null && curDate.before(countFreezeDate)) {
return ResResult.failed().setMsgValue("用户名或密码错误次数达到三次,请三分钟后再重试");
} 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);
Date curCodeDate = new Date();
if (code.equals(UserUtils.getEmailCode(account)) && curCodeDate.before(UserUtils.getEmailCodeExpTime(account))) {
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);
UserUtils.removeEmailCode(account);
UserUtils.removeEmailCodeExpTime(account);
log.info("登录成功!生成token!");
return ResResult.success().goRecord(loginVo);
} else {
return ResResult.failed().setMsgValue("验证码错误或已过期");
}
}
}
}
......@@ -115,4 +136,15 @@ public class LoginController {
return BaseResult.unauthorized();
}
@ApiOperation(value = "发送验证码", notes = "发送验证码到邮箱")
@GetMapping("send_code")
public BaseResult sendCode() {
String code = CommonUtil.getValidateCode();
String content = "感谢您使用实名制服务器" + "\n" + "此次登录验证码为:" + code + "(有效期三分钟)。验证码提供给他人可能导致账号被盗,请勿转发或泄露。" + "\n" + "--------------------------------------------------------------" + "此邮件由系统自动发送,请勿回复此邮件" + "--------------------------------------------------------------";
emailUtils.sendSimpleMail(account, "感谢您使用实名制服务器", content);
UserUtils.setEmailCode(account, code);
Date codeExpTime = new Date(System.currentTimeMillis() + 3 * 60 * 1000);
UserUtils.setEmailCodeExpTime(account, codeExpTime);
return BaseResult.success();
}
}
......@@ -18,6 +18,7 @@ import java.util.Map;
@WebFilter(filterName = "jwtFilter", urlPatterns = "/*")
public class JwtFilter implements Filter {
private static final String url1 = "/login";
private static final String url2 = "/send_code";
private static final String url3 = "/doc.html";
private static final String url4 = "/v2/api-docs";
private static final String url7 = "/swagger-resources";
......@@ -44,7 +45,7 @@ public class JwtFilter implements Filter {
boolean check = true;
String uri = request.getRequestURI();
if (uri.contains(url1)|| uri.contains(url3) || uri.contains(url4) || uri.contains(url7) || uri.contains(url8)) {
if (uri.contains(url1)|| uri.contains(url2) || uri.contains(url3) || uri.contains(url4) || uri.contains(url7) || uri.contains(url8)) {
if (uri.contains(url1)) {
uri = XssUtil.checkXSS(uri);
UserUtils.setUri(uri);
......
......@@ -13,6 +13,8 @@ public abstract class UserUtils {
static Map<String, String> tokenMap = new HashMap<>();
static Map<String, Date> tokenExpTimeMap = new HashMap<>();
static Map<String, Integer> errCntMap = new HashMap<>();
static Map<String, String> emailCodeMap = new HashMap<>();
static Map<String, Date> emailCodeExpTimeMap = new HashMap<>();
static Map<String, Date> countFreezeDateMap = new HashMap<>();
/**
* 线程变量,存放user实体类信息,即使是静态的也与其他线程也是隔离的
......@@ -112,4 +114,30 @@ public abstract class UserUtils {
public static void removeCountFreezeDate(String uId) {
countFreezeDateMap.remove(uId);
}
public static void setEmailCode(String email, String code) {
emailCodeMap.put(email, code);
}
public static String getEmailCode(String email) {
return emailCodeMap.get(email);
}
public static void removeEmailCode(String email) {
emailCodeMap.remove(email);
}
public static void setEmailCodeExpTime(String email, Date expTime) {
emailCodeExpTimeMap.put(email, expTime);
}
public static Date getEmailCodeExpTime(String email) {
return emailCodeExpTimeMap.get(email);
}
public static void removeEmailCodeExpTime(String email) {
emailCodeExpTimeMap.remove(email);
}
}
......@@ -17,6 +17,24 @@ import java.util.Locale;
@Slf4j
public class CommonUtil {
/**
* 获取随机验证码
*/
public static String getValidateCode() {
SecureRandom random = new SecureRandom();
try {
random = SecureRandom.getInstance("SHA1PRNG");
} catch (NoSuchAlgorithmException e) {
log.error(e.getMessage());
}
StringBuilder validateCode = new StringBuilder();
for (int i = 0; i < 6; i++) {
validateCode.append(random.nextInt(10));
}
return validateCode.toString();
}
/**
* 随机生成指定长度的字符串
*
......
package iot.sixiang.license.util;
import iot.sixiang.license.handler.IotLicenseException;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* Title: EmailUtils
* Description:
*
* @author YFW
* @version V1.0
* @date 2020-05-23
*/
@Slf4j
@Component
public class EmailUtils {
Logger logger = LoggerFactory.getLogger(EmailUtils.class);
@Value("${spring.mail.username}")
private String from;
@Resource
public JavaMailSender mailSender;
public void sendSimpleMail(String to, String subject, String content) {
SimpleMailMessage message = new SimpleMailMessage();
//发件人
message.setFrom(from);
//目标
message.setTo(to);
//主题
message.setSubject(subject);
//内容
message.setText(content);
try {
mailSender.send(message);
logger.info("一份简单邮件已发送。");
} catch (Exception e) {
logger.error("发送简单邮件时发生异常!", e);
throw new IotLicenseException(405, "短信邮件发送失败");
}
}
}
......@@ -5,6 +5,21 @@ spring:
name: iot_license #当前服务的名称
main:
allow-bean-definition-overriding: true
mail:
host: smtp.mxhichina.com
port: 465
username: dev_team@huahuico.com
password: Jas@7777777
to: MAllk33@163.com
default-encoding: UTF-8
properties:
mail:
smtp:
socketFactory:
port: 465
class: javax.net.ssl.SSLSocketFactory
fallback: false
## 配置输出日志
logging:
config: classpath:logback-spring.xml
......
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