Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
jinli gu
Eladmin
Commits
284c25a1
Commit
284c25a1
authored
Dec 01, 2019
by
dqjdda
Browse files
Merge branch '2.4dev' into 2.4opt
parents
175a2eb6
ccca30fc
Changes
48
Hide whitespace changes
Inline
Side-by-side
eladmin-common/src/main/java/me/zhengjie/annotation/Query.java
View file @
284c25a1
...
...
@@ -61,10 +61,8 @@ public @interface Query {
* 适用于简单连接查询,复杂的请自定义该注解,或者使用sql查询
*/
enum
Join
{
/** jie 2019-6-4 13:18:30 左连接 */
LEFT
/** jie 2019-6-4 13:18:30 右连接 */
,
RIGHT
/** jie 2019-6-4 13:18:30 左右连接 */
LEFT
,
RIGHT
}
}
...
...
eladmin-common/src/main/java/me/zhengjie/config/ElPermissionConfig.java
View file @
284c25a1
...
...
@@ -14,11 +14,6 @@ import java.util.stream.Collectors;
public
class
ElPermissionConfig
{
public
Boolean
check
(
String
...
permissions
){
// 如果是匿名访问的,就放行
String
anonymous
=
"anonymous"
;
if
(
Arrays
.
asList
(
permissions
).
contains
(
anonymous
)){
return
true
;
}
// 获取当前用户的所有权限
List
<
String
>
elPermissions
=
SecurityUtils
.
getUserDetails
().
getAuthorities
().
stream
().
map
(
GrantedAuthority:
:
getAuthority
).
collect
(
Collectors
.
toList
());
// 判断当前用户的所有权限是否包含接口上定义的权限
...
...
eladmin-common/src/main/java/me/zhengjie/config/SwaggerConfig.java
View file @
284c25a1
...
...
@@ -39,6 +39,9 @@ public class SwaggerConfig {
@Value
(
"${jwt.header}"
)
private
String
tokenHeader
;
@Value
(
"${jwt.token-start-with}"
)
private
String
tokenStartWith
;
@Value
(
"${swagger.enabled}"
)
private
Boolean
enabled
;
...
...
@@ -50,7 +53,7 @@ public class SwaggerConfig {
ticketPar
.
name
(
tokenHeader
).
description
(
"token"
)
.
modelRef
(
new
ModelRef
(
"string"
))
.
parameterType
(
"header"
)
.
defaultValue
(
"Bearer
"
)
.
defaultValue
(
tokenStartWith
+
"
"
)
.
required
(
true
)
.
build
();
pars
.
add
(
ticketPar
.
build
());
...
...
eladmin-common/src/main/java/me/zhengjie/exception/handler/GlobalExceptionHandler.java
View file @
284c25a1
...
...
@@ -32,16 +32,6 @@ public class GlobalExceptionHandler {
return
buildResponseEntity
(
ApiError
.
error
(
e
.
getMessage
()));
}
/**
* 处理 接口无权访问异常AccessDeniedException
*/
@ExceptionHandler
(
AccessDeniedException
.
class
)
public
ResponseEntity
handleAccessDeniedException
(
AccessDeniedException
e
){
// 打印堆栈信息
log
.
error
(
ThrowableUtil
.
getStackTrace
(
e
));
return
buildResponseEntity
(
ApiError
.
error
(
FORBIDDEN
.
value
(),
e
.
getMessage
()));
}
/**
* 处理自定义异常
*/
...
...
eladmin-common/src/main/java/me/zhengjie/utils/EncryptUtils.java
View file @
284c25a1
package
me.zhengjie.utils
;
import
org.springframework.util.DigestUtils
;
import
javax.crypto.Cipher
;
import
javax.crypto.SecretKey
;
import
javax.crypto.SecretKeyFactory
;
...
...
@@ -82,11 +81,4 @@ public class EncryptUtils {
}
return
b2
;
}
/**
* 密码加密
*/
public
static
String
encryptPassword
(
String
password
){
return
DigestUtils
.
md5DigestAsHex
(
password
.
getBytes
());
}
}
eladmin-common/src/main/java/me/zhengjie/utils/PageUtil.java
View file @
284c25a1
...
...
@@ -16,7 +16,6 @@ public class PageUtil extends cn.hutool.core.util.PageUtil {
public
static
List
toPage
(
int
page
,
int
size
,
List
list
)
{
int
fromIndex
=
page
*
size
;
int
toIndex
=
page
*
size
+
size
;
if
(
fromIndex
>
list
.
size
()){
return
new
ArrayList
();
}
else
if
(
toIndex
>=
list
.
size
())
{
...
...
@@ -43,7 +42,6 @@ public class PageUtil extends cn.hutool.core.util.PageUtil {
Map
<
String
,
Object
>
map
=
new
LinkedHashMap
<>(
2
);
map
.
put
(
"content"
,
object
);
map
.
put
(
"totalElements"
,
totalElements
);
return
map
;
}
...
...
eladmin-common/src/main/java/me/zhengjie/utils/RedisUtils.java
0 → 100644
View file @
284c25a1
package
me.zhengjie.utils
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.data.redis.connection.RedisConnection
;
import
org.springframework.data.redis.connection.RedisConnectionFactory
;
import
org.springframework.data.redis.core.*
;
import
org.springframework.stereotype.Component
;
import
org.springframework.util.CollectionUtils
;
import
java.util.*
;
import
java.util.concurrent.TimeUnit
;
/**
* @author /
*/
@Component
@SuppressWarnings
({
"unchecked"
,
"all"
})
public
class
RedisUtils
{
private
RedisTemplate
<
Object
,
Object
>
redisTemplate
;
@Value
(
"${jwt.online-key}"
)
private
String
onlineKey
;
public
RedisUtils
(
RedisTemplate
<
Object
,
Object
>
redisTemplate
)
{
this
.
redisTemplate
=
redisTemplate
;
}
// =============================common============================
/**
* 指定缓存失效时间
* @param key 键
* @param time 时间(秒)
*/
public
boolean
expire
(
String
key
,
long
time
)
{
try
{
if
(
time
>
0
)
{
redisTemplate
.
expire
(
key
,
time
,
TimeUnit
.
SECONDS
);
}
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
false
;
}
return
true
;
}
/**
* 根据 key 获取过期时间
* @param key 键 不能为null
* @return 时间(秒) 返回0代表为永久有效
*/
public
long
getExpire
(
Object
key
)
{
return
redisTemplate
.
getExpire
(
key
,
TimeUnit
.
SECONDS
);
}
/**
* 查找匹配key
* @param pattern key
* @return /
*/
public
List
<
String
>
scan
(
String
pattern
)
{
ScanOptions
options
=
ScanOptions
.
scanOptions
().
match
(
pattern
).
build
();
RedisConnectionFactory
factory
=
redisTemplate
.
getConnectionFactory
();
RedisConnection
rc
=
Objects
.
requireNonNull
(
factory
).
getConnection
();
Cursor
<
byte
[]>
cursor
=
rc
.
scan
(
options
);
List
<
String
>
result
=
new
ArrayList
<>();
while
(
cursor
.
hasNext
())
{
result
.
add
(
new
String
(
cursor
.
next
()));
}
try
{
RedisConnectionUtils
.
releaseConnection
(
rc
,
factory
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
return
result
;
}
/**
* 分页查询 key
* @param patternKey key
* @param page 页码
* @param size 每页数目
* @return /
*/
public
List
<
String
>
findKeysForPage
(
String
patternKey
,
int
page
,
int
size
)
{
ScanOptions
options
=
ScanOptions
.
scanOptions
().
match
(
patternKey
).
build
();
RedisConnectionFactory
factory
=
redisTemplate
.
getConnectionFactory
();
RedisConnection
rc
=
Objects
.
requireNonNull
(
factory
).
getConnection
();
Cursor
<
byte
[]>
cursor
=
rc
.
scan
(
options
);
List
<
String
>
result
=
new
ArrayList
<>(
size
);
int
tmpIndex
=
0
;
int
fromIndex
=
page
*
size
;
int
toIndex
=
page
*
size
+
size
;
while
(
cursor
.
hasNext
())
{
if
(
tmpIndex
>=
fromIndex
&&
tmpIndex
<
toIndex
)
{
result
.
add
(
new
String
(
cursor
.
next
()));
tmpIndex
++;
continue
;
}
// 获取到满足条件的数据后,就可以退出了
if
(
tmpIndex
>=
toIndex
)
{
break
;
}
tmpIndex
++;
cursor
.
next
();
}
try
{
RedisConnectionUtils
.
releaseConnection
(
rc
,
factory
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
return
result
;
}
/**
* 判断key是否存在
* @param key 键
* @return true 存在 false不存在
*/
public
boolean
hasKey
(
String
key
)
{
try
{
return
redisTemplate
.
hasKey
(
key
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
false
;
}
}
/**
* 删除缓存
* @param key 可以传一个值 或多个
*/
public
void
del
(
String
...
key
)
{
if
(
key
!=
null
&&
key
.
length
>
0
)
{
if
(
key
.
length
==
1
)
{
redisTemplate
.
delete
(
key
[
0
]);
}
else
{
redisTemplate
.
delete
(
CollectionUtils
.
arrayToList
(
key
));
}
}
}
// ============================String=============================
/**
* 普通缓存获取
* @param key 键
* @return 值
*/
public
Object
get
(
String
key
)
{
return
key
==
null
?
null
:
redisTemplate
.
opsForValue
().
get
(
key
);
}
/**
* 批量获取
* @param keys
* @return
*/
public
List
<
Object
>
multiGet
(
List
<
String
>
keys
)
{
Object
obj
=
redisTemplate
.
opsForValue
().
multiGet
(
Collections
.
singleton
(
keys
));
return
null
;
}
/**
* 普通缓存放入
* @param key 键
* @param value 值
* @return true成功 false失败
*/
public
boolean
set
(
String
key
,
Object
value
)
{
try
{
redisTemplate
.
opsForValue
().
set
(
key
,
value
);
return
true
;
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
false
;
}
}
/**
* 普通缓存放入并设置时间
* @param key 键
* @param value 值
* @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
* @return true成功 false 失败
*/
public
boolean
set
(
String
key
,
Object
value
,
long
time
)
{
try
{
if
(
time
>
0
)
{
redisTemplate
.
opsForValue
().
set
(
key
,
value
,
time
,
TimeUnit
.
SECONDS
);
}
else
{
set
(
key
,
value
);
}
return
true
;
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
false
;
}
}
/**
* 普通缓存放入并设置时间
* @param key 键
* @param value 值
* @param time 时间
* @param timeUnit 类型
* @return true成功 false 失败
*/
public
boolean
set
(
String
key
,
Object
value
,
long
time
,
TimeUnit
timeUnit
)
{
try
{
if
(
time
>
0
)
{
redisTemplate
.
opsForValue
().
set
(
key
,
value
,
time
,
timeUnit
);
}
else
{
set
(
key
,
value
);
}
return
true
;
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
false
;
}
}
// ================================Map=================================
/**
* HashGet
* @param key 键 不能为null
* @param item 项 不能为null
* @return 值
*/
public
Object
hget
(
String
key
,
String
item
)
{
return
redisTemplate
.
opsForHash
().
get
(
key
,
item
);
}
/**
* 获取hashKey对应的所有键值
* @param key 键
* @return 对应的多个键值
*/
public
Map
<
Object
,
Object
>
hmget
(
String
key
)
{
return
redisTemplate
.
opsForHash
().
entries
(
key
);
}
/**
* HashSet
* @param key 键
* @param map 对应多个键值
* @return true 成功 false 失败
*/
public
boolean
hmset
(
String
key
,
Map
<
String
,
Object
>
map
)
{
try
{
redisTemplate
.
opsForHash
().
putAll
(
key
,
map
);
return
true
;
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
false
;
}
}
/**
* HashSet 并设置时间
* @param key 键
* @param map 对应多个键值
* @param time 时间(秒)
* @return true成功 false失败
*/
public
boolean
hmset
(
String
key
,
Map
<
String
,
Object
>
map
,
long
time
)
{
try
{
redisTemplate
.
opsForHash
().
putAll
(
key
,
map
);
if
(
time
>
0
)
{
expire
(
key
,
time
);
}
return
true
;
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
false
;
}
}
/**
* 向一张hash表中放入数据,如果不存在将创建
*
* @param key 键
* @param item 项
* @param value 值
* @return true 成功 false失败
*/
public
boolean
hset
(
String
key
,
String
item
,
Object
value
)
{
try
{
redisTemplate
.
opsForHash
().
put
(
key
,
item
,
value
);
return
true
;
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
false
;
}
}
/**
* 向一张hash表中放入数据,如果不存在将创建
*
* @param key 键
* @param item 项
* @param value 值
* @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
* @return true 成功 false失败
*/
public
boolean
hset
(
String
key
,
String
item
,
Object
value
,
long
time
)
{
try
{
redisTemplate
.
opsForHash
().
put
(
key
,
item
,
value
);
if
(
time
>
0
)
{
expire
(
key
,
time
);
}
return
true
;
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
false
;
}
}
/**
* 删除hash表中的值
*
* @param key 键 不能为null
* @param item 项 可以使多个 不能为null
*/
public
void
hdel
(
String
key
,
Object
...
item
)
{
redisTemplate
.
opsForHash
().
delete
(
key
,
item
);
}
/**
* 判断hash表中是否有该项的值
*
* @param key 键 不能为null
* @param item 项 不能为null
* @return true 存在 false不存在
*/
public
boolean
hHasKey
(
String
key
,
String
item
)
{
return
redisTemplate
.
opsForHash
().
hasKey
(
key
,
item
);
}
/**
* hash递增 如果不存在,就会创建一个 并把新增后的值返回
*
* @param key 键
* @param item 项
* @param by 要增加几(大于0)
* @return
*/
public
double
hincr
(
String
key
,
String
item
,
double
by
)
{
return
redisTemplate
.
opsForHash
().
increment
(
key
,
item
,
by
);
}
/**
* hash递减
*
* @param key 键
* @param item 项
* @param by 要减少记(小于0)
* @return
*/
public
double
hdecr
(
String
key
,
String
item
,
double
by
)
{
return
redisTemplate
.
opsForHash
().
increment
(
key
,
item
,
-
by
);
}
// ============================set=============================
/**
* 根据key获取Set中的所有值
*
* @param key 键
* @return
*/
public
Set
<
Object
>
sGet
(
String
key
)
{
try
{
return
redisTemplate
.
opsForSet
().
members
(
key
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
null
;
}
}
/**
* 根据value从一个set中查询,是否存在
*
* @param key 键
* @param value 值
* @return true 存在 false不存在
*/
public
boolean
sHasKey
(
String
key
,
Object
value
)
{
try
{
return
redisTemplate
.
opsForSet
().
isMember
(
key
,
value
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
false
;
}
}
/**
* 将数据放入set缓存
*
* @param key 键
* @param values 值 可以是多个
* @return 成功个数
*/
public
long
sSet
(
String
key
,
Object
...
values
)
{
try
{
return
redisTemplate
.
opsForSet
().
add
(
key
,
values
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
0
;
}
}
/**
* 将set数据放入缓存
* @param key 键
* @param time 时间(秒)
* @param values 值 可以是多个
* @return 成功个数
*/
public
long
sSetAndTime
(
String
key
,
long
time
,
Object
...
values
)
{
try
{
Long
count
=
redisTemplate
.
opsForSet
().
add
(
key
,
values
);
if
(
time
>
0
)
{
expire
(
key
,
time
);
}
return
count
;
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
0
;
}
}
/**
* 获取set缓存的长度
* @param key 键
* @return
*/
public
long
sGetSetSize
(
String
key
)
{
try
{
return
redisTemplate
.
opsForSet
().
size
(
key
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
0
;
}
}
/**
* 移除值为value的
* @param key 键
* @param values 值 可以是多个
* @return 移除的个数
*/
public
long
setRemove
(
String
key
,
Object
...
values
)
{
try
{
Long
count
=
redisTemplate
.
opsForSet
().
remove
(
key
,
values
);
return
count
;
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
0
;
}
}
// ===============================list=================================
/**
* 获取list缓存的内容
* @param key 键
* @param start 开始
* @param end 结束 0 到 -1代表所有值
* @return
*/
public
List
<
Object
>
lGet
(
String
key
,
long
start
,
long
end
)
{
try
{
return
redisTemplate
.
opsForList
().
range
(
key
,
start
,
end
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
null
;
}
}
/**
* 获取list缓存的长度
* @param key 键
* @return
*/
public
long
lGetListSize
(
String
key
)
{
try
{
return
redisTemplate
.
opsForList
().
size
(
key
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
0
;
}
}
/**
* 通过索引 获取list中的值
* @param key 键
* @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
* @return
*/
public
Object
lGetIndex
(
String
key
,
long
index
)
{
try
{
return
redisTemplate
.
opsForList
().
index
(
key
,
index
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
null
;
}
}
/**
* 将list放入缓存
* @param key 键
* @param value 值
* @return
*/
public
boolean
lSet
(
String
key
,
Object
value
)
{
try
{
redisTemplate
.
opsForList
().
rightPush
(
key
,
value
);
return
true
;
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
false
;
}
}
/**
* 将list放入缓存
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return
*/
public
boolean
lSet
(
String
key
,
Object
value
,
long
time
)
{
try
{
redisTemplate
.
opsForList
().
rightPush
(
key
,
value
);
if
(
time
>
0
)
{
expire
(
key
,
time
);
}
return
true
;
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
false
;
}
}
/**
* 将list放入缓存
* @param key 键
* @param value 值
* @return
*/
public
boolean
lSet
(
String
key
,
List
<
Object
>
value
)
{
try
{
redisTemplate
.
opsForList
().
rightPushAll
(
key
,
value
);
return
true
;
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
false
;
}
}
/**
* 将list放入缓存
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return
*/
public
boolean
lSet
(
String
key
,
List
<
Object
>
value
,
long
time
)
{
try
{
redisTemplate
.
opsForList
().
rightPushAll
(
key
,
value
);
if
(
time
>
0
)
{
expire
(
key
,
time
);
}
return
true
;
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
false
;
}
}
/**
* 根据索引修改list中的某条数据
* @param key 键
* @param index 索引
* @param value 值
* @return /
*/
public
boolean
lUpdateIndex
(
String
key
,
long
index
,
Object
value
)
{
try
{
redisTemplate
.
opsForList
().
set
(
key
,
index
,
value
);
return
true
;
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
false
;
}
}
/**
* 移除N个值为value
* @param key 键
* @param count 移除多少个
* @param value 值
* @return 移除的个数
*/
public
long
lRemove
(
String
key
,
long
count
,
Object
value
)
{
try
{
return
redisTemplate
.
opsForList
().
remove
(
key
,
count
,
value
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
0
;
}
}
}
eladmin-common/src/main/java/me/zhengjie/utils/SecurityUtils.java
View file @
284c25a1
...
...
@@ -3,6 +3,7 @@ package me.zhengjie.utils;
import
cn.hutool.json.JSONObject
;
import
me.zhengjie.exception.BadRequestException
;
import
org.springframework.http.HttpStatus
;
import
org.springframework.security.core.context.SecurityContextHolder
;
import
org.springframework.security.core.userdetails.UserDetails
;
/**
...
...
@@ -15,7 +16,7 @@ public class SecurityUtils {
public
static
UserDetails
getUserDetails
()
{
UserDetails
userDetails
;
try
{
userDetails
=
(
UserDetails
)
org
.
springframework
.
security
.
core
.
context
.
SecurityContextHolder
.
getContext
().
getAuthentication
().
getPrincipal
();
userDetails
=
(
UserDetails
)
SecurityContextHolder
.
getContext
().
getAuthentication
().
getPrincipal
();
}
catch
(
Exception
e
)
{
throw
new
BadRequestException
(
HttpStatus
.
UNAUTHORIZED
,
"登录状态过期"
);
}
...
...
@@ -30,13 +31,4 @@ public class SecurityUtils {
Object
obj
=
getUserDetails
();
return
new
JSONObject
(
obj
).
get
(
"username"
,
String
.
class
);
}
/**
* 获取系统用户id
* @return 系统用户id
*/
public
static
Long
getUserId
(){
Object
obj
=
getUserDetails
();
return
new
JSONObject
(
obj
).
get
(
"id"
,
Long
.
class
);
}
}
eladmin-common/src/main/java/me/zhengjie/utils/ValidationUtil.java
View file @
284c25a1
...
...
@@ -2,6 +2,7 @@ package me.zhengjie.utils;
import
cn.hutool.core.util.ObjectUtil
;
import
me.zhengjie.exception.BadRequestException
;
import
org.hibernate.validator.internal.constraintvalidators.hv.EmailValidator
;
/**
* 验证工具
...
...
@@ -23,11 +24,7 @@ public class ValidationUtil{
/**
* 验证是否为邮箱
*/
public
static
boolean
isEmail
(
String
string
)
{
if
(
string
==
null
){
return
false
;
}
String
regEx1
=
"^([a-z0-9A-Z]+[-|.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$"
;
return
string
.
matches
(
regEx1
);
public
static
boolean
isEmail
(
String
email
)
{
return
new
EmailValidator
().
isValid
(
email
,
null
);
}
}
eladmin-system/pom.xml
View file @
284c25a1
...
...
@@ -13,7 +13,7 @@
<name>
核心模块
</name>
<properties>
<jjwt.version>
0.
9.1
</jjwt.version>
<jjwt.version>
0.
10.6
</jjwt.version>
</properties>
<dependencies>
...
...
@@ -45,7 +45,17 @@
<!--jwt-->
<dependency>
<groupId>
io.jsonwebtoken
</groupId>
<artifactId>
jjwt
</artifactId>
<artifactId>
jjwt-api
</artifactId>
<version>
${jjwt.version}
</version>
</dependency>
<dependency>
<groupId>
io.jsonwebtoken
</groupId>
<artifactId>
jjwt-impl
</artifactId>
<version>
${jjwt.version}
</version>
</dependency>
<dependency>
<groupId>
io.jsonwebtoken
</groupId>
<artifactId>
jjwt-jackson
</artifactId>
<version>
${jjwt.version}
</version>
</dependency>
...
...
eladmin-system/src/main/java/me/zhengjie/config/ConfigurerAdapter.java
View file @
284c25a1
package
me.zhengjie.config
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.web.servlet.config.annotation.CorsRegistry
;
import
org.springframework.web.cors.CorsConfiguration
;
import
org.springframework.web.cors.UrlBasedCorsConfigurationSource
;
import
org.springframework.web.filter.CorsFilter
;
import
org.springframework.web.servlet.config.annotation.EnableWebMvc
;
import
org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry
;
import
org.springframework.web.servlet.config.annotation.WebMvcConfigurer
;
import
java.nio.file.Paths
;
/**
* WebMvcConfigurer
...
...
@@ -24,20 +26,22 @@ public class ConfigurerAdapter implements WebMvcConfigurer {
@Value
(
"${file.avatar}"
)
private
String
avatar
;
@Override
public
void
addCorsMappings
(
CorsRegistry
registry
)
{
registry
.
addMapping
(
"/**"
)
.
allowCredentials
(
true
)
.
allowedHeaders
(
"*"
)
.
allowedOrigins
(
"*"
)
.
allowedMethods
(
"GET"
,
"POST"
,
"PUT"
,
"DELETE"
);
@Bean
public
CorsFilter
corsFilter
()
{
UrlBasedCorsConfigurationSource
source
=
new
UrlBasedCorsConfigurationSource
();
CorsConfiguration
config
=
new
CorsConfiguration
();
config
.
setAllowCredentials
(
true
);
config
.
addAllowedOrigin
(
"*"
);
config
.
addAllowedHeader
(
"*"
);
config
.
addAllowedMethod
(
"*"
);
source
.
registerCorsConfiguration
(
"/**"
,
config
);
return
new
CorsFilter
(
source
);
}
@Override
public
void
addResourceHandlers
(
ResourceHandlerRegistry
registry
)
{
String
avatarUtl
=
Paths
.
get
(
avatar
).
normalize
().
toUri
().
toASCIIString
(
);
String
pathUtl
=
Paths
.
get
(
path
).
normalize
().
toUri
().
toASCIIString
(
);
String
avatarUtl
=
"file:"
+
avatar
.
replace
(
"\\"
,
"/"
);
String
pathUtl
=
"file:"
+
path
.
replace
(
"\\"
,
"/"
);
registry
.
addResourceHandler
(
"/avatar/**"
).
addResourceLocations
(
avatarUtl
).
setCachePeriod
(
0
);
registry
.
addResourceHandler
(
"/file/**"
).
addResourceLocations
(
pathUtl
).
setCachePeriod
(
0
);
registry
.
addResourceHandler
(
"/**"
).
addResourceLocations
(
"classpath:/META-INF/resources/"
).
setCachePeriod
(
0
);
...
...
eladmin-system/src/main/java/me/zhengjie/modules/monitor/rest/LimitController.java
View file @
284c25a1
...
...
@@ -4,11 +4,9 @@ import io.swagger.annotations.Api;
import
io.swagger.annotations.ApiOperation
;
import
me.zhengjie.annotation.AnonymousAccess
;
import
me.zhengjie.annotation.Limit
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
java.util.concurrent.atomic.AtomicInteger
;
/**
...
...
@@ -26,7 +24,7 @@ public class LimitController {
* 测试限流注解,下面配置说明该接口 60秒内最多只能访问 10次,保存到redis的键名为 limit_test,
*/
@GetMapping
@
PreAuthorize
(
"@el.check('a
nonymous
')"
)
@
A
nonymous
Access
@ApiOperation
(
"测试"
)
@Limit
(
key
=
"test"
,
period
=
60
,
count
=
10
,
name
=
"testLimit"
,
prefix
=
"limit"
)
public
int
testLimit
()
{
...
...
eladmin-system/src/main/java/me/zhengjie/modules/monitor/rest/RedisController.java
deleted
100644 → 0
View file @
175a2eb6
package
me.zhengjie.modules.monitor.rest
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiOperation
;
import
me.zhengjie.aop.log.Log
;
import
me.zhengjie.modules.monitor.domain.vo.RedisVo
;
import
me.zhengjie.modules.monitor.service.RedisService
;
import
org.springframework.data.domain.Pageable
;
import
org.springframework.http.HttpStatus
;
import
org.springframework.http.ResponseEntity
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.web.bind.annotation.*
;
import
javax.servlet.http.HttpServletResponse
;
import
java.io.IOException
;
/**
* @author Zheng Jie
* @date 2018-12-10
*/
@RestController
@RequestMapping
(
"/api/redis"
)
@Api
(
tags
=
"系统:Redis缓存管理"
)
public
class
RedisController
{
private
final
RedisService
redisService
;
public
RedisController
(
RedisService
redisService
)
{
this
.
redisService
=
redisService
;
}
@Log
(
"查询Redis缓存"
)
@GetMapping
@ApiOperation
(
"查询Redis缓存"
)
@PreAuthorize
(
"@el.check('redis:list')"
)
public
ResponseEntity
getRedis
(
String
key
,
Pageable
pageable
){
return
new
ResponseEntity
<>(
redisService
.
findByKey
(
key
,
pageable
),
HttpStatus
.
OK
);
}
@Log
(
"导出数据"
)
@ApiOperation
(
"导出数据"
)
@GetMapping
(
value
=
"/download"
)
@PreAuthorize
(
"@el.check('redis:list')"
)
public
void
download
(
HttpServletResponse
response
,
String
key
)
throws
IOException
{
redisService
.
download
(
redisService
.
findByKey
(
key
),
response
);
}
@Log
(
"删除Redis缓存"
)
@DeleteMapping
@ApiOperation
(
"删除Redis缓存"
)
@PreAuthorize
(
"@el.check('redis:del')"
)
public
ResponseEntity
delete
(
@RequestBody
RedisVo
resources
){
redisService
.
delete
(
resources
.
getKey
());
return
new
ResponseEntity
(
HttpStatus
.
OK
);
}
@Log
(
"清空Redis缓存"
)
@DeleteMapping
(
value
=
"/all"
)
@ApiOperation
(
"清空Redis缓存"
)
@PreAuthorize
(
"@el.check('redis:del')"
)
public
ResponseEntity
deleteAll
(){
redisService
.
deleteAll
();
return
new
ResponseEntity
(
HttpStatus
.
OK
);
}
}
eladmin-system/src/main/java/me/zhengjie/modules/monitor/service/RedisService.java
deleted
100644 → 0
View file @
175a2eb6
package
me.zhengjie.modules.monitor.service
;
import
me.zhengjie.modules.monitor.domain.vo.RedisVo
;
import
org.springframework.data.domain.Page
;
import
org.springframework.data.domain.Pageable
;
import
javax.servlet.http.HttpServletResponse
;
import
java.io.IOException
;
import
java.util.List
;
/**
* 可自行扩展
* @author Zheng Jie
* @date 2018-12-10
*/
public
interface
RedisService
{
/**
* 根据KEY查询
* @param key 键
* @param pageable 分页参数
* @return /
*/
Page
findByKey
(
String
key
,
Pageable
pageable
);
/**
* findById
* @param key 键
* @return /
*/
List
<
RedisVo
>
findByKey
(
String
key
);
/**
* 查询验证码的值
* @param key 键
* @return /
*/
String
getCodeVal
(
String
key
);
/**
* 保存验证码
* @param key 键
* @param val 值
*/
void
saveCode
(
String
key
,
Object
val
);
/**
* delete
* @param key 键
*/
void
delete
(
String
key
);
/**
* 清空缓存
*/
void
deleteAll
();
/**
* 导出数据
* @param redisVos /
* @param response /
* @throws IOException /
*/
void
download
(
List
<
RedisVo
>
redisVos
,
HttpServletResponse
response
)
throws
IOException
;
}
eladmin-system/src/main/java/me/zhengjie/modules/monitor/service/impl/RedisServiceImpl.java
deleted
100644 → 0
View file @
175a2eb6
package
me.zhengjie.modules.monitor.service.impl
;
import
cn.hutool.core.util.ObjectUtil
;
import
me.zhengjie.modules.monitor.domain.vo.RedisVo
;
import
me.zhengjie.modules.monitor.service.RedisService
;
import
me.zhengjie.utils.FileUtil
;
import
me.zhengjie.utils.PageUtil
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.data.domain.Page
;
import
org.springframework.data.domain.PageImpl
;
import
org.springframework.data.domain.Pageable
;
import
org.springframework.data.redis.core.RedisTemplate
;
import
org.springframework.stereotype.Service
;
import
javax.servlet.http.HttpServletResponse
;
import
java.io.IOException
;
import
java.util.*
;
import
java.util.concurrent.TimeUnit
;
import
java.util.stream.Collectors
;
/**
* @author Zheng Jie
* @date 2018-12-10
*/
@Service
@SuppressWarnings
({
"unchecked"
,
"all"
})
public
class
RedisServiceImpl
implements
RedisService
{
private
final
RedisTemplate
redisTemplate
;
@Value
(
"${loginCode.expiration}"
)
private
Long
expiration
;
@Value
(
"${jwt.online}"
)
private
String
onlineKey
;
@Value
(
"${jwt.codeKey}"
)
private
String
codeKey
;
public
RedisServiceImpl
(
RedisTemplate
redisTemplate
)
{
this
.
redisTemplate
=
redisTemplate
;
}
@Override
public
Page
<
RedisVo
>
findByKey
(
String
key
,
Pageable
pageable
){
List
<
RedisVo
>
redisVos
=
findByKey
(
key
);
return
new
PageImpl
<
RedisVo
>(
PageUtil
.
toPage
(
pageable
.
getPageNumber
(),
pageable
.
getPageSize
(),
redisVos
),
pageable
,
redisVos
.
size
());
}
@Override
public
List
<
RedisVo
>
findByKey
(
String
key
)
{
List
<
RedisVo
>
redisVos
=
new
ArrayList
<>();
if
(!
"*"
.
equals
(
key
)){
key
=
"*"
+
key
+
"*"
;
}
Set
<
String
>
keys
=
redisTemplate
.
keys
(
key
);
for
(
String
s
:
keys
)
{
// 过滤掉权限的缓存
if
(
s
.
contains
(
"role::loadPermissionByUser"
)
||
s
.
contains
(
"user::loadUserByUsername"
)
||
s
.
contains
(
onlineKey
)
||
s
.
contains
(
codeKey
))
{
continue
;
}
RedisVo
redisVo
=
new
RedisVo
(
s
,
Objects
.
requireNonNull
(
redisTemplate
.
opsForValue
().
get
(
s
)).
toString
());
redisVos
.
add
(
redisVo
);
}
return
redisVos
;
}
@Override
public
void
delete
(
String
key
)
{
redisTemplate
.
delete
(
key
);
}
@Override
public
void
deleteAll
()
{
Set
<
String
>
keys
=
redisTemplate
.
keys
(
"*"
);
redisTemplate
.
delete
(
keys
.
stream
().
filter
(
s
->
!
s
.
contains
(
onlineKey
)).
filter
(
s
->
!
s
.
contains
(
codeKey
)).
collect
(
Collectors
.
toList
()));
}
@Override
public
String
getCodeVal
(
String
key
)
{
try
{
return
Objects
.
requireNonNull
(
redisTemplate
.
opsForValue
().
get
(
key
)).
toString
();
}
catch
(
Exception
e
){
return
""
;
}
}
@Override
public
void
saveCode
(
String
key
,
Object
val
)
{
redisTemplate
.
opsForValue
().
set
(
key
,
val
);
redisTemplate
.
expire
(
key
,
expiration
,
TimeUnit
.
MINUTES
);
}
@Override
public
void
download
(
List
<
RedisVo
>
redisVos
,
HttpServletResponse
response
)
throws
IOException
{
List
<
Map
<
String
,
Object
>>
list
=
new
ArrayList
<>();
for
(
RedisVo
redisVo
:
redisVos
)
{
Map
<
String
,
Object
>
map
=
new
LinkedHashMap
<>();
map
.
put
(
"key"
,
redisVo
.
getKey
());
map
.
put
(
"value"
,
redisVo
.
getValue
());
list
.
add
(
map
);
}
FileUtil
.
downloadExcel
(
list
,
response
);
}
}
eladmin-system/src/main/java/me/zhengjie/modules/security/config/SecurityConfig.java
View file @
284c25a1
package
me.zhengjie.modules.security.config
;
import
me.zhengjie.annotation.AnonymousAccess
;
import
me.zhengjie.modules.security.security.JwtAuthenticationEntryPoint
;
import
me.zhengjie.modules.security.security.JwtAuthorizationTokenFilter
;
import
me.zhengjie.modules.security.service.JwtUserDetailsServiceImpl
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
me.zhengjie.modules.security.security.*
;
import
org.springframework.context.ApplicationContext
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.http.HttpMethod
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.security.authentication.AuthenticationManager
;
import
org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
;
import
org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity
;
import
org.springframework.security.config.annotation.web.builders.HttpSecurity
;
import
org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
;
...
...
@@ -22,6 +15,7 @@ import org.springframework.security.config.http.SessionCreationPolicy;
import
org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
;
import
org.springframework.security.crypto.password.PasswordEncoder
;
import
org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
;
import
org.springframework.web.filter.CorsFilter
;
import
org.springframework.web.method.HandlerMethod
;
import
org.springframework.web.servlet.mvc.method.RequestMappingInfo
;
import
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
;
...
...
@@ -34,103 +28,98 @@ import java.util.Set;
*/
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity
(
prePostEnabled
=
true
)
@EnableGlobalMethodSecurity
(
prePostEnabled
=
true
,
securedEnabled
=
true
)
public
class
SecurityConfig
extends
WebSecurityConfigurerAdapter
{
private
final
JwtAuthenticationEntryPoint
unauthorizedHandl
er
;
private
final
Jwt
UserDetailsServiceImpl
jwtUserDetailsService
;
private
final
TokenProvider
tokenProvid
er
;
private
final
CorsFilter
corsFilter
;
private
final
Jwt
AuthenticationEntryPoint
authenticationErrorHandler
;
private
final
JwtAccessDeniedHandler
jwtAccessDeniedHandler
;
private
final
ApplicationContext
applicationContext
;
/** 自定义基于JWT的安全过滤器 */
private
final
JwtAuthorizationTokenFilter
authenticationTokenFilter
;
@Value
(
"${jwt.header}"
)
private
String
tokenHeader
;
public
SecurityConfig
(
JwtAuthenticationEntryPoint
unauthorizedHandler
,
JwtUserDetailsServiceImpl
jwtUserDetailsService
,
JwtAuthorizationTokenFilter
authenticationTokenFilter
,
ApplicationContext
applicationContext
)
{
this
.
unauthorizedHandler
=
unauthorizedHandler
;
this
.
jwtUserDetailsService
=
jwtUserDetailsService
;
this
.
authenticationTokenFilter
=
authenticationTokenFilter
;
public
SecurityConfig
(
TokenProvider
tokenProvider
,
CorsFilter
corsFilter
,
JwtAuthenticationEntryPoint
authenticationErrorHandler
,
JwtAccessDeniedHandler
jwtAccessDeniedHandler
,
ApplicationContext
applicationContext
)
{
this
.
tokenProvider
=
tokenProvider
;
this
.
corsFilter
=
corsFilter
;
this
.
authenticationErrorHandler
=
authenticationErrorHandler
;
this
.
jwtAccessDeniedHandler
=
jwtAccessDeniedHandler
;
this
.
applicationContext
=
applicationContext
;
}
@Autowired
public
void
configureGlobal
(
AuthenticationManagerBuilder
auth
)
throws
Exception
{
auth
.
userDetailsService
(
jwtUserDetailsService
)
.
passwordEncoder
(
passwordEncoderBean
());
}
@Bean
GrantedAuthorityDefaults
grantedAuthorityDefaults
()
{
//
Remove the
ROLE_
prefix
//
去除
ROLE_
前缀
return
new
GrantedAuthorityDefaults
(
""
);
}
@Bean
public
PasswordEncoder
passwordEncoderBean
()
{
public
PasswordEncoder
passwordEncoder
()
{
// 密码加密方式
return
new
BCryptPasswordEncoder
();
}
@Bean
@Override
public
AuthenticationManager
authenticationManagerBean
()
throws
Exception
{
return
super
.
authenticationManagerBean
();
}
@Override
protected
void
configure
(
HttpSecurity
httpSecurity
)
throws
Exception
{
// 搜寻
匿名标记 url:
PreAuthorize("hasAnyRole('anonymous')") 和 PreAuthorize("@el.check('anonymous')") 和
AnonymousAccess
// 搜寻匿名标记 url:
@
AnonymousAccess
Map
<
RequestMappingInfo
,
HandlerMethod
>
handlerMethodMap
=
applicationContext
.
getBean
(
RequestMappingHandlerMapping
.
class
).
getHandlerMethods
();
Set
<
String
>
anonymousUrls
=
new
HashSet
<>();
for
(
Map
.
Entry
<
RequestMappingInfo
,
HandlerMethod
>
infoEntry
:
handlerMethodMap
.
entrySet
())
{
HandlerMethod
handlerMethod
=
infoEntry
.
getValue
();
AnonymousAccess
anonymousAccess
=
handlerMethod
.
getMethodAnnotation
(
AnonymousAccess
.
class
);
PreAuthorize
preAuthorize
=
handlerMethod
.
getMethodAnnotation
(
PreAuthorize
.
class
);
if
(
null
!=
preAuthorize
&&
preAuthorize
.
value
().
toLowerCase
().
contains
(
"anonymous"
))
{
anonymousUrls
.
addAll
(
infoEntry
.
getKey
().
getPatternsCondition
().
getPatterns
());
}
else
if
(
null
!=
anonymousAccess
&&
null
==
preAuthorize
)
{
if
(
null
!=
anonymousAccess
)
{
anonymousUrls
.
addAll
(
infoEntry
.
getKey
().
getPatternsCondition
().
getPatterns
());
}
}
httpSecurity
// 禁用 CSRF
.
csrf
().
disable
()
.
addFilterBefore
(
corsFilter
,
UsernamePasswordAuthenticationFilter
.
class
)
// 授权异常
.
exceptionHandling
().
authenticationEntryPoint
(
unauthorizedHandler
).
and
()
.
exceptionHandling
()
.
authenticationEntryPoint
(
authenticationErrorHandler
)
.
accessDeniedHandler
(
jwtAccessDeniedHandler
)
// 防止iframe 造成跨域
.
and
()
.
headers
()
.
frameOptions
()
.
disable
()
// 不创建会话
.
sessionManagement
().
sessionCreationPolicy
(
SessionCreationPolicy
.
STATELESS
).
and
()
// 过滤请求
.
and
()
.
sessionManagement
()
.
sessionCreationPolicy
(
SessionCreationPolicy
.
STATELESS
)
.
and
()
.
authorizeRequests
()
// 静态资源等等
.
antMatchers
(
HttpMethod
.
GET
,
"/*.html"
,
"/**/*.html"
,
"/**/*.css"
,
"/**/*.js"
,
"/webSocket/**"
).
anonymous
()
// swagger
start
"/webSocket/**"
).
permitAll
()
// swagger
文档
.
antMatchers
(
"/swagger-ui.html"
).
permitAll
()
.
antMatchers
(
"/swagger-resources/**"
).
permitAll
()
.
antMatchers
(
"/webjars/**"
).
permitAll
()
.
antMatchers
(
"/*/api-docs"
).
permitAll
()
// swagger end
// 文件
.
antMatchers
(
"/avatar/**"
).
permitAll
()
.
antMatchers
(
"/file/**"
).
permitAll
()
// 阿里巴巴 druid
.
antMatchers
(
"/druid/**"
).
permitAll
()
// 放行OPTIONS请求
.
antMatchers
(
HttpMethod
.
OPTIONS
,
"/**"
).
permitAll
()
.
antMatchers
(
"/druid/**"
).
permitAll
()
// 自定义匿名访问所有url放行 : 允许 匿名和带权限以及登录用户访问
// 自定义匿名访问所有url放行 : 允许匿名和带权限以及登录用户访问
.
antMatchers
(
anonymousUrls
.
toArray
(
new
String
[
0
])).
permitAll
()
// 所有请求都需要认证
.
anyRequest
().
authenticated
()
// 防止iframe 造成跨域
.
and
().
headers
().
frameOptions
().
disable
();
httpSecurity
.
addFilterBefore
(
authenticationTokenFilter
,
UsernamePasswordAuthenticationFilter
.
class
);
.
and
().
apply
(
securityConfigurerAdapter
());
}
private
TokenConfigurer
securityConfigurerAdapter
()
{
return
new
TokenConfigurer
(
tokenProvider
);
}
}
eladmin-system/src/main/java/me/zhengjie/modules/security/config/SecurityProperties.java
0 → 100644
View file @
284c25a1
package
me.zhengjie.modules.security.config
;
import
lombok.Data
;
import
org.springframework.boot.context.properties.ConfigurationProperties
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.stereotype.Component
;
/**
* Jwt参数配置
* @author Zheng Jie
* @date 2019年11月28日
*/
@Data
@Configuration
@ConfigurationProperties
(
prefix
=
"jwt"
)
public
class
SecurityProperties
{
/** Request Headers : Authorization */
private
String
header
;
/** 令牌前缀,最后留个空格 Bearer */
private
String
tokenStartWith
;
/** 必须使用最少88位的Base64对该令牌进行编码 */
private
String
base64Secret
;
/** 令牌过期时间 此处单位/毫秒 */
private
Long
tokenValidityInSeconds
;
/** 在线用户 key,根据 key 查询 redis 中在线用户的数据 */
private
String
onlineKey
;
/** 验证码 key */
private
String
codeKey
;
public
String
getTokenStartWith
()
{
return
tokenStartWith
+
" "
;
}
}
eladmin-system/src/main/java/me/zhengjie/modules/security/rest/Auth
entication
Controller.java
→
eladmin-system/src/main/java/me/zhengjie/modules/security/rest/AuthController.java
View file @
284c25a1
...
...
@@ -8,25 +8,28 @@ import lombok.extern.slf4j.Slf4j;
import
me.zhengjie.annotation.AnonymousAccess
;
import
me.zhengjie.aop.log.Log
;
import
me.zhengjie.exception.BadRequestException
;
import
me.zhengjie.modules.monitor.service.RedisService
;
import
me.zhengjie.modules.security.security.AuthInfo
;
import
me.zhengjie.modules.security.security.AuthUser
;
import
me.zhengjie.modules.security.security.ImgResult
;
import
me.zhengjie.modules.security.security.JwtUser
;
import
me.zhengjie.modules.security.config.SecurityProperties
;
import
me.zhengjie.modules.security.security.TokenProvider
;
import
me.zhengjie.modules.security.security.vo.AuthUser
;
import
me.zhengjie.modules.security.security.vo.JwtUser
;
import
me.zhengjie.modules.security.service.OnlineUserService
;
import
me.zhengjie.utils.EncryptUtils
;
import
me.zhengjie.modules.security.utils.JwtTokenUtil
;
import
me.zhengjie.utils.RedisUtils
;
import
me.zhengjie.utils.SecurityUtils
;
import
me.zhengjie.utils.StringUtils
;
import
org.springframework.beans.factory.annotation.Qualifier
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.http.HttpStatus
;
import
org.springframework.http.ResponseEntity
;
import
org.springframework.security.authentication.AccountExpiredException
;
import
org.springframework.security.authentication.UsernamePasswordAuthenticationToken
;
import
org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
;
import
org.springframework.security.core.Authentication
;
import
org.springframework.security.core.context.SecurityContextHolder
;
import
org.springframework.security.core.userdetails.UserDetailsService
;
import
org.springframework.validation.annotation.Validated
;
import
org.springframework.web.bind.annotation.*
;
import
javax.servlet.http.HttpServletRequest
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.concurrent.TimeUnit
;
/**
* @author Zheng Jie
...
...
@@ -37,24 +40,24 @@ import javax.servlet.http.HttpServletRequest;
@RestController
@RequestMapping
(
"/auth"
)
@Api
(
tags
=
"系统:系统授权接口"
)
public
class
AuthenticationController
{
@Value
(
"${jwt.codeKey}"
)
private
String
codeKey
;
private
final
JwtTokenUtil
jwtTokenUtil
;
private
final
RedisService
redisService
;
public
class
AuthController
{
@Value
(
"${loginCode.expiration}"
)
private
Long
expiration
;
private
final
SecurityProperties
properties
;
private
final
RedisUtils
redisUtils
;
private
final
UserDetailsService
userDetailsService
;
private
final
OnlineUserService
onlineUserService
;
private
final
TokenProvider
tokenProvider
;
private
final
AuthenticationManagerBuilder
authenticationManagerBuilder
;
public
Auth
entication
Controller
(
JwtTokenUtil
jwtTokenUtil
,
RedisService
redisService
,
@Qualifier
(
"jwtUserDetailsServiceImpl"
)
UserDetailsService
userDetailsService
,
OnlineUserService
onlineUserService
)
{
this
.
jwtTokenUtil
=
jwtTokenUtil
;
this
.
redis
Service
=
redis
Service
;
public
AuthController
(
SecurityProperties
properties
,
RedisUtils
redisUtils
,
UserDetailsService
userDetailsService
,
OnlineUserService
onlineUserService
,
TokenProvider
tokenProvider
,
AuthenticationManagerBuilder
authenticationManagerBuilder
)
{
this
.
properties
=
properties
;
this
.
redis
Utils
=
redis
Utils
;
this
.
userDetailsService
=
userDetailsService
;
this
.
onlineUserService
=
onlineUserService
;
this
.
tokenProvider
=
tokenProvider
;
this
.
authenticationManagerBuilder
=
authenticationManagerBuilder
;
}
@Log
(
"用户登录"
)
...
...
@@ -62,32 +65,32 @@ public class AuthenticationController {
@AnonymousAccess
@PostMapping
(
value
=
"/login"
)
public
ResponseEntity
login
(
@Validated
@RequestBody
AuthUser
authUser
,
HttpServletRequest
request
){
// 查询验证码
String
code
=
redisService
.
getCodeVal
(
authUser
.
getUuid
());
String
code
=
(
String
)
redisUtils
.
get
(
authUser
.
getUuid
());
// 清除验证码
redis
Service
.
del
ete
(
authUser
.
getUuid
());
redis
Utils
.
del
(
authUser
.
getUuid
());
if
(
StringUtils
.
isBlank
(
code
))
{
throw
new
BadRequestException
(
"验证码已过期"
);
throw
new
BadRequestException
(
"验证码
不存在或
已过期"
);
}
if
(
StringUtils
.
isBlank
(
authUser
.
getCode
())
||
!
authUser
.
getCode
().
equalsIgnoreCase
(
code
))
{
throw
new
BadRequestException
(
"验证码错误"
);
}
final
JwtUser
jwtUser
=
(
JwtUser
)
userDetailsService
.
loadUserByUsername
(
authUser
.
getUsername
());
UsernamePasswordAuthenticationToken
authenticationToken
=
new
UsernamePasswordAuthenticationToken
(
authUser
.
getUsername
(),
authUser
.
getPassword
());
if
(!
jwtUser
.
getPassword
().
equals
(
EncryptUtils
.
encryptPassword
(
authUser
.
getPassword
()))){
throw
new
AccountExpiredException
(
"密码错误"
);
}
if
(!
jwtUser
.
isEnabled
()){
throw
new
AccountExpiredException
(
"账号已停用,请联系管理员"
);
}
Authentication
authentication
=
authenticationManagerBuilder
.
getObject
().
authenticate
(
authenticationToken
);
SecurityContextHolder
.
getContext
().
setAuthentication
(
authentication
);
// 生成令牌
final
String
token
=
jwtTokenUtil
.
generateToken
(
jwtUser
);
String
token
=
tokenProvider
.
createToken
(
authentication
);
final
JwtUser
jwtUser
=
(
JwtUser
)
authentication
.
getPrincipal
();
// 保存在线信息
onlineUserService
.
save
(
jwtUser
,
token
,
request
);
// 返回 token
return
ResponseEntity
.
ok
(
new
AuthInfo
(
token
,
jwtUser
));
// 返回 token 与 用户信息
Map
<
String
,
Object
>
authInfo
=
new
HashMap
<
String
,
Object
>(
2
){{
put
(
"token"
,
properties
.
getTokenStartWith
()
+
token
);
put
(
"user"
,
jwtUser
);
}};
return
ResponseEntity
.
ok
(
authInfo
);
}
@ApiOperation
(
"获取用户信息"
)
...
...
@@ -97,26 +100,32 @@ public class AuthenticationController {
return
ResponseEntity
.
ok
(
jwtUser
);
}
@ApiOperation
(
"获取验证码"
)
@AnonymousAccess
@ApiOperation
(
"获取验证码"
)
@GetMapping
(
value
=
"/code"
)
public
ImgResult
getCode
(){
public
ResponseEntity
getCode
(){
// 算术类型 https://gitee.com/whvse/EasyCaptcha
ArithmeticCaptcha
captcha
=
new
ArithmeticCaptcha
(
111
,
36
);
// 几位数运算,默认是两位
captcha
.
setLen
(
2
);
// 获取运算的结果
:5
// 获取运算的结果
String
result
=
captcha
.
text
();
String
uuid
=
codeKey
+
IdUtil
.
simpleUUID
();
redisService
.
saveCode
(
uuid
,
result
);
return
new
ImgResult
(
captcha
.
toBase64
(),
uuid
);
String
uuid
=
properties
.
getCodeKey
()
+
IdUtil
.
simpleUUID
();
// 保存
redisUtils
.
set
(
uuid
,
result
,
expiration
,
TimeUnit
.
MINUTES
);
// 验证码信息
Map
<
String
,
Object
>
imgResult
=
new
HashMap
<
String
,
Object
>(
2
){{
put
(
"img"
,
captcha
.
toBase64
());
put
(
"uuid"
,
uuid
);
}};
return
ResponseEntity
.
ok
(
imgResult
);
}
@ApiOperation
(
"退出登录"
)
@AnonymousAccess
@DeleteMapping
(
value
=
"/logout"
)
public
ResponseEntity
logout
(
HttpServletRequest
request
){
onlineUserService
.
logout
(
jwtTokenUtil
.
getToken
(
request
));
onlineUserService
.
logout
(
tokenProvider
.
getToken
(
request
));
return
new
ResponseEntity
(
HttpStatus
.
OK
);
}
}
eladmin-system/src/main/java/me/zhengjie/modules/security/security/AuthInfo.java
deleted
100644 → 0
View file @
175a2eb6
package
me.zhengjie.modules.security.security
;
import
lombok.AllArgsConstructor
;
import
lombok.Getter
;
import
java.io.Serializable
;
/**
* @author Zheng Jie
* @date 2018-11-23
* 返回token
*/
@Getter
@AllArgsConstructor
public
class
AuthInfo
implements
Serializable
{
private
final
String
token
;
private
final
JwtUser
user
;
}
eladmin-system/src/main/java/me/zhengjie/modules/security/security/ImgResult.java
deleted
100644 → 0
View file @
175a2eb6
package
me.zhengjie.modules.security.security
;
import
lombok.AllArgsConstructor
;
import
lombok.Data
;
/**
* @author Zheng Jie
* @date 2019-6-5 17:29:57
*/
@Data
@AllArgsConstructor
public
class
ImgResult
{
private
String
img
;
private
String
uuid
;
}
Prev
1
2
3
Next
Write
Preview
Supports
Markdown
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