Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
I
ioc_sixiang_license
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
zengtianlai3
ioc_sixiang_license
Commits
d2d3afe0
Commit
d2d3afe0
authored
Aug 05, 2022
by
zengtianlai3
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
修改多因子认证
parent
914a09b3
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
169 additions
and
17 deletions
+169
-17
pom.xml
license/pom.xml
+6
-0
LoginController.java
.../java/iot/sixiang/license/controller/LoginController.java
+48
-16
JwtFilter.java
license/src/main/java/iot/sixiang/license/jwt/JwtFilter.java
+2
-1
UserUtils.java
license/src/main/java/iot/sixiang/license/jwt/UserUtils.java
+28
-0
CommonUtil.java
...se/src/main/java/iot/sixiang/license/util/CommonUtil.java
+18
-0
EmailUtils.java
...se/src/main/java/iot/sixiang/license/util/EmailUtils.java
+52
-0
application.yml
license/src/main/resources/application.yml
+15
-0
No files found.
license/pom.xml
View file @
d2d3afe0
...
@@ -144,6 +144,12 @@
...
@@ -144,6 +144,12 @@
<version>
1.9
</version>
<version>
1.9
</version>
</dependency>
</dependency>
<!--邮件-->
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-mail
</artifactId>
</dependency>
<dependency>
<dependency>
<groupId>
com.sixiang.iot
</groupId>
<groupId>
com.sixiang.iot
</groupId>
<artifactId>
server-license
</artifactId>
<artifactId>
server-license
</artifactId>
...
...
license/src/main/java/iot/sixiang/license/controller/LoginController.java
View file @
d2d3afe0
...
@@ -12,11 +12,16 @@ import iot.sixiang.license.log.MyLog;
...
@@ -12,11 +12,16 @@ import iot.sixiang.license.log.MyLog;
import
iot.sixiang.license.model.BaseResult
;
import
iot.sixiang.license.model.BaseResult
;
import
iot.sixiang.license.model.ResResult
;
import
iot.sixiang.license.model.ResResult
;
import
iot.sixiang.license.model.vo.LoginVo
;
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
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.util.DigestUtils
;
import
org.springframework.util.DigestUtils
;
import
org.springframework.util.StringUtils
;
import
org.springframework.web.bind.annotation.*
;
import
org.springframework.web.bind.annotation.*
;
import
springfox.documentation.annotations.ApiIgnore
;
import
springfox.documentation.annotations.ApiIgnore
;
import
javax.annotation.Resource
;
import
java.util.Date
;
import
java.util.Date
;
import
java.util.HashMap
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.Map
;
...
@@ -30,6 +35,12 @@ import java.util.Map;
...
@@ -30,6 +35,12 @@ import java.util.Map;
@Api
(
value
=
"登录模块"
,
tags
=
{
"登录模块"
})
@Api
(
value
=
"登录模块"
,
tags
=
{
"登录模块"
})
public
class
LoginController
{
public
class
LoginController
{
@Resource
EmailUtils
emailUtils
;
@Value
(
"${spring.mail.to}"
)
private
String
account
;
//模拟数据库
//模拟数据库
static
Map
<
String
,
LoginUser
>
userMap
=
new
HashMap
<>();
static
Map
<
String
,
LoginUser
>
userMap
=
new
HashMap
<>();
...
@@ -43,17 +54,20 @@ public class LoginController {
...
@@ -43,17 +54,20 @@ public class LoginController {
*/
*/
@ApiOperation
(
value
=
"登录接口"
,
notes
=
"登录接口"
)
@ApiOperation
(
value
=
"登录接口"
,
notes
=
"登录接口"
)
@GetMapping
(
"login"
)
@GetMapping
(
"login"
)
@MyLog
(
title
=
"登录"
,
optParam
=
"#{userName},#{password}"
,
businessType
=
BusinessType
.
OTHER
)
@MyLog
(
title
=
"登录"
,
optParam
=
"#{userName},#{password}
,#{code}
"
,
businessType
=
BusinessType
.
OTHER
)
@ApiImplicitParams
({
@ApiImplicitParams
({
@ApiImplicitParam
(
name
=
"userName"
,
value
=
"用户名"
,
required
=
true
),
@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
())
{
for
(
LoginUser
dbUser
:
userMap
.
values
())
{
String
account
=
dbUser
.
getUserName
();
String
name
=
dbUser
.
getUserName
();
String
psw
=
account
+
dbUser
.
getPassword
();
String
psw
=
name
+
dbUser
.
getPassword
();
if
(
DigestUtils
.
md5DigestAsHex
(
account
.
getBytes
()).
equals
(
userName
)
&&
DigestUtils
.
md5DigestAsHex
(
psw
.
getBytes
()).
equals
(
password
))
{
if
(
DigestUtils
.
md5DigestAsHex
(
name
.
getBytes
()).
equals
(
userName
)
&&
DigestUtils
.
md5DigestAsHex
(
psw
.
getBytes
()).
equals
(
password
))
{
// 登录错误次数
// 登录错误次数
Integer
errCnt
=
UserUtils
.
getErrCnt
(
userName
);
Integer
errCnt
=
UserUtils
.
getErrCnt
(
userName
);
Date
countFreezeDate
=
UserUtils
.
getCountFreezeDate
(
userName
);
Date
countFreezeDate
=
UserUtils
.
getCountFreezeDate
(
userName
);
...
@@ -61,15 +75,22 @@ public class LoginController {
...
@@ -61,15 +75,22 @@ public class LoginController {
if
(
errCnt
!=
null
&&
errCnt
>=
3
&&
countFreezeDate
!=
null
&&
curDate
.
before
(
countFreezeDate
))
{
if
(
errCnt
!=
null
&&
errCnt
>=
3
&&
countFreezeDate
!=
null
&&
curDate
.
before
(
countFreezeDate
))
{
return
ResResult
.
failed
().
setMsgValue
(
"用户名或密码错误次数达到三次,请三分钟后再重试"
);
return
ResResult
.
failed
().
setMsgValue
(
"用户名或密码错误次数达到三次,请三分钟后再重试"
);
}
else
{
}
else
{
String
token
=
JwtUtil
.
createToken
(
dbUser
);
Date
curCodeDate
=
new
Date
();
LoginVo
loginVo
=
new
LoginVo
();
if
(
code
.
equals
(
UserUtils
.
getEmailCode
(
account
))
&&
curCodeDate
.
before
(
UserUtils
.
getEmailCodeExpTime
(
account
)))
{
loginVo
.
setAuthorization
(
token
);
String
token
=
JwtUtil
.
createToken
(
dbUser
);
UserUtils
.
setToken
(
dbUser
.
getUserId
(),
token
);
LoginVo
loginVo
=
new
LoginVo
();
UserUtils
.
setTokenExp
(
dbUser
.
getUserId
(),
JwtUtil
.
getTokenExp
());
loginVo
.
setAuthorization
(
token
);
UserUtils
.
removeErrCnt
(
userName
);
UserUtils
.
setToken
(
dbUser
.
getUserId
(),
token
);
UserUtils
.
removeCountFreezeDate
(
userName
);
UserUtils
.
setTokenExp
(
dbUser
.
getUserId
(),
JwtUtil
.
getTokenExp
());
log
.
info
(
"登录成功!生成token!"
);
UserUtils
.
removeErrCnt
(
userName
);
return
ResResult
.
success
().
goRecord
(
loginVo
);
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 {
...
@@ -115,4 +136,15 @@ public class LoginController {
return
BaseResult
.
unauthorized
();
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
();
}
}
}
license/src/main/java/iot/sixiang/license/jwt/JwtFilter.java
View file @
d2d3afe0
...
@@ -18,6 +18,7 @@ import java.util.Map;
...
@@ -18,6 +18,7 @@ import java.util.Map;
@WebFilter
(
filterName
=
"jwtFilter"
,
urlPatterns
=
"/*"
)
@WebFilter
(
filterName
=
"jwtFilter"
,
urlPatterns
=
"/*"
)
public
class
JwtFilter
implements
Filter
{
public
class
JwtFilter
implements
Filter
{
private
static
final
String
url1
=
"/login"
;
private
static
final
String
url1
=
"/login"
;
private
static
final
String
url2
=
"/send_code"
;
private
static
final
String
url3
=
"/doc.html"
;
private
static
final
String
url3
=
"/doc.html"
;
private
static
final
String
url4
=
"/v2/api-docs"
;
private
static
final
String
url4
=
"/v2/api-docs"
;
private
static
final
String
url7
=
"/swagger-resources"
;
private
static
final
String
url7
=
"/swagger-resources"
;
...
@@ -44,7 +45,7 @@ public class JwtFilter implements Filter {
...
@@ -44,7 +45,7 @@ public class JwtFilter implements Filter {
boolean
check
=
true
;
boolean
check
=
true
;
String
uri
=
request
.
getRequestURI
();
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
(
url
2
)
||
uri
.
contains
(
url
3
)
||
uri
.
contains
(
url4
)
||
uri
.
contains
(
url7
)
||
uri
.
contains
(
url8
))
{
if
(
uri
.
contains
(
url1
))
{
if
(
uri
.
contains
(
url1
))
{
uri
=
XssUtil
.
checkXSS
(
uri
);
uri
=
XssUtil
.
checkXSS
(
uri
);
UserUtils
.
setUri
(
uri
);
UserUtils
.
setUri
(
uri
);
...
...
license/src/main/java/iot/sixiang/license/jwt/UserUtils.java
View file @
d2d3afe0
...
@@ -13,6 +13,8 @@ public abstract class UserUtils {
...
@@ -13,6 +13,8 @@ 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
<>();
static
Map
<
String
,
Integer
>
errCntMap
=
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
<>();
static
Map
<
String
,
Date
>
countFreezeDateMap
=
new
HashMap
<>();
/**
/**
* 线程变量,存放user实体类信息,即使是静态的也与其他线程也是隔离的
* 线程变量,存放user实体类信息,即使是静态的也与其他线程也是隔离的
...
@@ -112,4 +114,30 @@ public abstract class UserUtils {
...
@@ -112,4 +114,30 @@ public abstract class UserUtils {
public
static
void
removeCountFreezeDate
(
String
uId
)
{
public
static
void
removeCountFreezeDate
(
String
uId
)
{
countFreezeDateMap
.
remove
(
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
);
}
}
}
license/src/main/java/iot/sixiang/license/util/CommonUtil.java
View file @
d2d3afe0
...
@@ -17,6 +17,24 @@ import java.util.Locale;
...
@@ -17,6 +17,24 @@ import java.util.Locale;
@Slf4j
@Slf4j
public
class
CommonUtil
{
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
();
}
/**
/**
* 随机生成指定长度的字符串
* 随机生成指定长度的字符串
*
*
...
...
license/src/main/java/iot/sixiang/license/util/EmailUtils.java
0 → 100644
View file @
d2d3afe0
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
,
"短信邮件发送失败"
);
}
}
}
license/src/main/resources/application.yml
View file @
d2d3afe0
...
@@ -5,6 +5,21 @@ spring:
...
@@ -5,6 +5,21 @@ spring:
name
:
iot_license
#当前服务的名称
name
:
iot_license
#当前服务的名称
main
:
main
:
allow-bean-definition-overriding
:
true
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
:
logging
:
config
:
classpath:logback-spring.xml
config
:
classpath:logback-spring.xml
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment