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
"src/main/java/vscode:/vscode.git/clone" did not exist on "b6ba87394bf3abadbbd07cf5a15d7cbf599ad632"
Commit
284c25a1
authored
Dec 01, 2019
by
dqjdda
Browse files
Merge branch '2.4dev' into 2.4opt
parents
175a2eb6
ccca30fc
Changes
48
Show 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 {
...
@@ -61,10 +61,8 @@ public @interface Query {
* 适用于简单连接查询,复杂的请自定义该注解,或者使用sql查询
* 适用于简单连接查询,复杂的请自定义该注解,或者使用sql查询
*/
*/
enum
Join
{
enum
Join
{
/** jie 2019-6-4 13:18:30 左连接 */
/** jie 2019-6-4 13:18:30 左右连接 */
LEFT
LEFT
,
RIGHT
/** jie 2019-6-4 13:18:30 右连接 */
,
RIGHT
}
}
}
}
...
...
eladmin-common/src/main/java/me/zhengjie/config/ElPermissionConfig.java
View file @
284c25a1
...
@@ -14,11 +14,6 @@ import java.util.stream.Collectors;
...
@@ -14,11 +14,6 @@ import java.util.stream.Collectors;
public
class
ElPermissionConfig
{
public
class
ElPermissionConfig
{
public
Boolean
check
(
String
...
permissions
){
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
());
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 {
...
@@ -39,6 +39,9 @@ public class SwaggerConfig {
@Value
(
"${jwt.header}"
)
@Value
(
"${jwt.header}"
)
private
String
tokenHeader
;
private
String
tokenHeader
;
@Value
(
"${jwt.token-start-with}"
)
private
String
tokenStartWith
;
@Value
(
"${swagger.enabled}"
)
@Value
(
"${swagger.enabled}"
)
private
Boolean
enabled
;
private
Boolean
enabled
;
...
@@ -50,7 +53,7 @@ public class SwaggerConfig {
...
@@ -50,7 +53,7 @@ public class SwaggerConfig {
ticketPar
.
name
(
tokenHeader
).
description
(
"token"
)
ticketPar
.
name
(
tokenHeader
).
description
(
"token"
)
.
modelRef
(
new
ModelRef
(
"string"
))
.
modelRef
(
new
ModelRef
(
"string"
))
.
parameterType
(
"header"
)
.
parameterType
(
"header"
)
.
defaultValue
(
"Bearer
"
)
.
defaultValue
(
tokenStartWith
+
"
"
)
.
required
(
true
)
.
required
(
true
)
.
build
();
.
build
();
pars
.
add
(
ticketPar
.
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 {
...
@@ -32,16 +32,6 @@ public class GlobalExceptionHandler {
return
buildResponseEntity
(
ApiError
.
error
(
e
.
getMessage
()));
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
;
package
me.zhengjie.utils
;
import
org.springframework.util.DigestUtils
;
import
javax.crypto.Cipher
;
import
javax.crypto.Cipher
;
import
javax.crypto.SecretKey
;
import
javax.crypto.SecretKey
;
import
javax.crypto.SecretKeyFactory
;
import
javax.crypto.SecretKeyFactory
;
...
@@ -82,11 +81,4 @@ public class EncryptUtils {
...
@@ -82,11 +81,4 @@ public class EncryptUtils {
}
}
return
b2
;
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 {
...
@@ -16,7 +16,6 @@ public class PageUtil extends cn.hutool.core.util.PageUtil {
public
static
List
toPage
(
int
page
,
int
size
,
List
list
)
{
public
static
List
toPage
(
int
page
,
int
size
,
List
list
)
{
int
fromIndex
=
page
*
size
;
int
fromIndex
=
page
*
size
;
int
toIndex
=
page
*
size
+
size
;
int
toIndex
=
page
*
size
+
size
;
if
(
fromIndex
>
list
.
size
()){
if
(
fromIndex
>
list
.
size
()){
return
new
ArrayList
();
return
new
ArrayList
();
}
else
if
(
toIndex
>=
list
.
size
())
{
}
else
if
(
toIndex
>=
list
.
size
())
{
...
@@ -43,7 +42,6 @@ public class PageUtil extends cn.hutool.core.util.PageUtil {
...
@@ -43,7 +42,6 @@ public class PageUtil extends cn.hutool.core.util.PageUtil {
Map
<
String
,
Object
>
map
=
new
LinkedHashMap
<>(
2
);
Map
<
String
,
Object
>
map
=
new
LinkedHashMap
<>(
2
);
map
.
put
(
"content"
,
object
);
map
.
put
(
"content"
,
object
);
map
.
put
(
"totalElements"
,
totalElements
);
map
.
put
(
"totalElements"
,
totalElements
);
return
map
;
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;
...
@@ -3,6 +3,7 @@ package me.zhengjie.utils;
import
cn.hutool.json.JSONObject
;
import
cn.hutool.json.JSONObject
;
import
me.zhengjie.exception.BadRequestException
;
import
me.zhengjie.exception.BadRequestException
;
import
org.springframework.http.HttpStatus
;
import
org.springframework.http.HttpStatus
;
import
org.springframework.security.core.context.SecurityContextHolder
;
import
org.springframework.security.core.userdetails.UserDetails
;
import
org.springframework.security.core.userdetails.UserDetails
;
/**
/**
...
@@ -15,7 +16,7 @@ public class SecurityUtils {
...
@@ -15,7 +16,7 @@ public class SecurityUtils {
public
static
UserDetails
getUserDetails
()
{
public
static
UserDetails
getUserDetails
()
{
UserDetails
userDetails
;
UserDetails
userDetails
;
try
{
try
{
userDetails
=
(
UserDetails
)
org
.
springframework
.
security
.
core
.
context
.
SecurityContextHolder
.
getContext
().
getAuthentication
().
getPrincipal
();
userDetails
=
(
UserDetails
)
SecurityContextHolder
.
getContext
().
getAuthentication
().
getPrincipal
();
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
throw
new
BadRequestException
(
HttpStatus
.
UNAUTHORIZED
,
"登录状态过期"
);
throw
new
BadRequestException
(
HttpStatus
.
UNAUTHORIZED
,
"登录状态过期"
);
}
}
...
@@ -30,13 +31,4 @@ public class SecurityUtils {
...
@@ -30,13 +31,4 @@ public class SecurityUtils {
Object
obj
=
getUserDetails
();
Object
obj
=
getUserDetails
();
return
new
JSONObject
(
obj
).
get
(
"username"
,
String
.
class
);
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;
...
@@ -2,6 +2,7 @@ package me.zhengjie.utils;
import
cn.hutool.core.util.ObjectUtil
;
import
cn.hutool.core.util.ObjectUtil
;
import
me.zhengjie.exception.BadRequestException
;
import
me.zhengjie.exception.BadRequestException
;
import
org.hibernate.validator.internal.constraintvalidators.hv.EmailValidator
;
/**
/**
* 验证工具
* 验证工具
...
@@ -23,11 +24,7 @@ public class ValidationUtil{
...
@@ -23,11 +24,7 @@ public class ValidationUtil{
/**
/**
* 验证是否为邮箱
* 验证是否为邮箱
*/
*/
public
static
boolean
isEmail
(
String
string
)
{
public
static
boolean
isEmail
(
String
email
)
{
if
(
string
==
null
){
return
new
EmailValidator
().
isValid
(
email
,
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
);
}
}
}
}
eladmin-system/pom.xml
View file @
284c25a1
...
@@ -13,7 +13,7 @@
...
@@ -13,7 +13,7 @@
<name>
核心模块
</name>
<name>
核心模块
</name>
<properties>
<properties>
<jjwt.version>
0.
9.1
</jjwt.version>
<jjwt.version>
0.
10.6
</jjwt.version>
</properties>
</properties>
<dependencies>
<dependencies>
...
@@ -45,7 +45,17 @@
...
@@ -45,7 +45,17 @@
<!--jwt-->
<!--jwt-->
<dependency>
<dependency>
<groupId>
io.jsonwebtoken
</groupId>
<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>
<version>
${jjwt.version}
</version>
</dependency>
</dependency>
...
...
eladmin-system/src/main/java/me/zhengjie/config/ConfigurerAdapter.java
View file @
284c25a1
package
me.zhengjie.config
;
package
me.zhengjie.config
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
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.EnableWebMvc
;
import
org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry
;
import
org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry
;
import
org.springframework.web.servlet.config.annotation.WebMvcConfigurer
;
import
org.springframework.web.servlet.config.annotation.WebMvcConfigurer
;
import
java.nio.file.Paths
;
/**
/**
* WebMvcConfigurer
* WebMvcConfigurer
...
@@ -24,20 +26,22 @@ public class ConfigurerAdapter implements WebMvcConfigurer {
...
@@ -24,20 +26,22 @@ public class ConfigurerAdapter implements WebMvcConfigurer {
@Value
(
"${file.avatar}"
)
@Value
(
"${file.avatar}"
)
private
String
avatar
;
private
String
avatar
;
@Override
@Bean
public
void
addCorsMappings
(
CorsRegistry
registry
)
{
public
CorsFilter
corsFilter
()
{
registry
.
addMapping
(
"/**"
)
UrlBasedCorsConfigurationSource
source
=
new
UrlBasedCorsConfigurationSource
();
.
allowCredentials
(
true
)
CorsConfiguration
config
=
new
CorsConfiguration
();
.
allowedHeaders
(
"*"
)
config
.
setAllowCredentials
(
true
);
.
allowedOrigins
(
"*"
)
config
.
addAllowedOrigin
(
"*"
);
.
allowedMethods
(
"GET"
,
"POST"
,
"PUT"
,
"DELETE"
);
config
.
addAllowedHeader
(
"*"
);
config
.
addAllowedMethod
(
"*"
);
source
.
registerCorsConfiguration
(
"/**"
,
config
);
return
new
CorsFilter
(
source
);
}
}
@Override
@Override
public
void
addResourceHandlers
(
ResourceHandlerRegistry
registry
)
{
public
void
addResourceHandlers
(
ResourceHandlerRegistry
registry
)
{
String
avatarUtl
=
Paths
.
get
(
avatar
).
normalize
().
toUri
().
toASCIIString
(
);
String
avatarUtl
=
"file:"
+
avatar
.
replace
(
"\\"
,
"/"
);
String
pathUtl
=
Paths
.
get
(
path
).
normalize
().
toUri
().
toASCIIString
(
);
String
pathUtl
=
"file:"
+
path
.
replace
(
"\\"
,
"/"
);
registry
.
addResourceHandler
(
"/avatar/**"
).
addResourceLocations
(
avatarUtl
).
setCachePeriod
(
0
);
registry
.
addResourceHandler
(
"/avatar/**"
).
addResourceLocations
(
avatarUtl
).
setCachePeriod
(
0
);
registry
.
addResourceHandler
(
"/file/**"
).
addResourceLocations
(
pathUtl
).
setCachePeriod
(
0
);
registry
.
addResourceHandler
(
"/file/**"
).
addResourceLocations
(
pathUtl
).
setCachePeriod
(
0
);
registry
.
addResourceHandler
(
"/**"
).
addResourceLocations
(
"classpath:/META-INF/resources/"
).
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;
...
@@ -4,11 +4,9 @@ import io.swagger.annotations.Api;
import
io.swagger.annotations.ApiOperation
;
import
io.swagger.annotations.ApiOperation
;
import
me.zhengjie.annotation.AnonymousAccess
;
import
me.zhengjie.annotation.AnonymousAccess
;
import
me.zhengjie.annotation.Limit
;
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.GetMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
org.springframework.web.bind.annotation.RestController
;
import
java.util.concurrent.atomic.AtomicInteger
;
import
java.util.concurrent.atomic.AtomicInteger
;
/**
/**
...
@@ -26,7 +24,7 @@ public class LimitController {
...
@@ -26,7 +24,7 @@ public class LimitController {
* 测试限流注解,下面配置说明该接口 60秒内最多只能访问 10次,保存到redis的键名为 limit_test,
* 测试限流注解,下面配置说明该接口 60秒内最多只能访问 10次,保存到redis的键名为 limit_test,
*/
*/
@GetMapping
@GetMapping
@
PreAuthorize
(
"@el.check('a
nonymous
')"
)
@
A
nonymous
Access
@ApiOperation
(
"测试"
)
@ApiOperation
(
"测试"
)
@Limit
(
key
=
"test"
,
period
=
60
,
count
=
10
,
name
=
"testLimit"
,
prefix
=
"limit"
)
@Limit
(
key
=
"test"
,
period
=
60
,
count
=
10
,
name
=
"testLimit"
,
prefix
=
"limit"
)
public
int
testLimit
()
{
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
;
package
me.zhengjie.modules.security.config
;
import
me.zhengjie.annotation.AnonymousAccess
;
import
me.zhengjie.annotation.AnonymousAccess
;
import
me.zhengjie.modules.security.security.JwtAuthenticationEntryPoint
;
import
me.zhengjie.modules.security.security.*
;
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
org.springframework.context.ApplicationContext
;
import
org.springframework.context.ApplicationContext
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.http.HttpMethod
;
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.method.configuration.EnableGlobalMethodSecurity
;
import
org.springframework.security.config.annotation.web.builders.HttpSecurity
;
import
org.springframework.security.config.annotation.web.builders.HttpSecurity
;
import
org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
;
import
org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
;
...
@@ -22,6 +15,7 @@ import org.springframework.security.config.http.SessionCreationPolicy;
...
@@ -22,6 +15,7 @@ import org.springframework.security.config.http.SessionCreationPolicy;
import
org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
;
import
org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
;
import
org.springframework.security.crypto.password.PasswordEncoder
;
import
org.springframework.security.crypto.password.PasswordEncoder
;
import
org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
;
import
org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
;
import
org.springframework.web.filter.CorsFilter
;
import
org.springframework.web.method.HandlerMethod
;
import
org.springframework.web.method.HandlerMethod
;
import
org.springframework.web.servlet.mvc.method.RequestMappingInfo
;
import
org.springframework.web.servlet.mvc.method.RequestMappingInfo
;
import
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
;
import
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
;
...
@@ -34,76 +28,70 @@ import java.util.Set;
...
@@ -34,76 +28,70 @@ import java.util.Set;
*/
*/
@Configuration
@Configuration
@EnableWebSecurity
@EnableWebSecurity
@EnableGlobalMethodSecurity
(
prePostEnabled
=
true
)
@EnableGlobalMethodSecurity
(
prePostEnabled
=
true
,
securedEnabled
=
true
)
public
class
SecurityConfig
extends
WebSecurityConfigurerAdapter
{
public
class
SecurityConfig
extends
WebSecurityConfigurerAdapter
{
private
final
JwtAuthenticationEntryPoint
unauthorizedHandl
er
;
private
final
TokenProvider
tokenProvid
er
;
private
final
CorsFilter
corsFilter
;
private
final
Jwt
UserDetailsServiceImpl
jwtUserDetailsService
;
private
final
Jwt
AuthenticationEntryPoint
authenticationErrorHandler
;
private
final
JwtAccessDeniedHandler
jwtAccessDeniedHandler
;
private
final
ApplicationContext
applicationContext
;
private
final
ApplicationContext
applicationContext
;
/** 自定义基于JWT的安全过滤器 */
public
SecurityConfig
(
TokenProvider
tokenProvider
,
CorsFilter
corsFilter
,
JwtAuthenticationEntryPoint
authenticationErrorHandler
,
JwtAccessDeniedHandler
jwtAccessDeniedHandler
,
ApplicationContext
applicationContext
)
{
private
final
JwtAuthorizationTokenFilter
authenticationTokenFilter
;
this
.
tokenProvider
=
tokenProvider
;
this
.
corsFilter
=
corsFilter
;
@Value
(
"${jwt.header}"
)
this
.
authenticationErrorHandler
=
authenticationErrorHandler
;
private
String
tokenHeader
;
this
.
jwtAccessDeniedHandler
=
jwtAccessDeniedHandler
;
public
SecurityConfig
(
JwtAuthenticationEntryPoint
unauthorizedHandler
,
JwtUserDetailsServiceImpl
jwtUserDetailsService
,
JwtAuthorizationTokenFilter
authenticationTokenFilter
,
ApplicationContext
applicationContext
)
{
this
.
unauthorizedHandler
=
unauthorizedHandler
;
this
.
jwtUserDetailsService
=
jwtUserDetailsService
;
this
.
authenticationTokenFilter
=
authenticationTokenFilter
;
this
.
applicationContext
=
applicationContext
;
this
.
applicationContext
=
applicationContext
;
}
}
@Autowired
public
void
configureGlobal
(
AuthenticationManagerBuilder
auth
)
throws
Exception
{
auth
.
userDetailsService
(
jwtUserDetailsService
)
.
passwordEncoder
(
passwordEncoderBean
());
}
@Bean
@Bean
GrantedAuthorityDefaults
grantedAuthorityDefaults
()
{
GrantedAuthorityDefaults
grantedAuthorityDefaults
()
{
//
Remove the
ROLE_
prefix
//
去除
ROLE_
前缀
return
new
GrantedAuthorityDefaults
(
""
);
return
new
GrantedAuthorityDefaults
(
""
);
}
}
@Bean
@Bean
public
PasswordEncoder
passwordEncoderBean
()
{
public
PasswordEncoder
passwordEncoder
()
{
// 密码加密方式
return
new
BCryptPasswordEncoder
();
return
new
BCryptPasswordEncoder
();
}
}
@Bean
@Override
public
AuthenticationManager
authenticationManagerBean
()
throws
Exception
{
return
super
.
authenticationManagerBean
();
}
@Override
@Override
protected
void
configure
(
HttpSecurity
httpSecurity
)
throws
Exception
{
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
();
Map
<
RequestMappingInfo
,
HandlerMethod
>
handlerMethodMap
=
applicationContext
.
getBean
(
RequestMappingHandlerMapping
.
class
).
getHandlerMethods
();
Set
<
String
>
anonymousUrls
=
new
HashSet
<>();
Set
<
String
>
anonymousUrls
=
new
HashSet
<>();
for
(
Map
.
Entry
<
RequestMappingInfo
,
HandlerMethod
>
infoEntry
:
handlerMethodMap
.
entrySet
())
{
for
(
Map
.
Entry
<
RequestMappingInfo
,
HandlerMethod
>
infoEntry
:
handlerMethodMap
.
entrySet
())
{
HandlerMethod
handlerMethod
=
infoEntry
.
getValue
();
HandlerMethod
handlerMethod
=
infoEntry
.
getValue
();
AnonymousAccess
anonymousAccess
=
handlerMethod
.
getMethodAnnotation
(
AnonymousAccess
.
class
);
AnonymousAccess
anonymousAccess
=
handlerMethod
.
getMethodAnnotation
(
AnonymousAccess
.
class
);
PreAuthorize
preAuthorize
=
handlerMethod
.
getMethodAnnotation
(
PreAuthorize
.
class
);
if
(
null
!=
anonymousAccess
)
{
if
(
null
!=
preAuthorize
&&
preAuthorize
.
value
().
toLowerCase
().
contains
(
"anonymous"
))
{
anonymousUrls
.
addAll
(
infoEntry
.
getKey
().
getPatternsCondition
().
getPatterns
());
}
else
if
(
null
!=
anonymousAccess
&&
null
==
preAuthorize
)
{
anonymousUrls
.
addAll
(
infoEntry
.
getKey
().
getPatternsCondition
().
getPatterns
());
anonymousUrls
.
addAll
(
infoEntry
.
getKey
().
getPatternsCondition
().
getPatterns
());
}
}
}
}
httpSecurity
httpSecurity
// 禁用 CSRF
// 禁用 CSRF
.
csrf
().
disable
()
.
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
()
.
authorizeRequests
()
// 静态资源等等
.
antMatchers
(
.
antMatchers
(
HttpMethod
.
GET
,
HttpMethod
.
GET
,
"/*.html"
,
"/*.html"
,
...
@@ -111,26 +99,27 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
...
@@ -111,26 +99,27 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
"/**/*.css"
,
"/**/*.css"
,
"/**/*.js"
,
"/**/*.js"
,
"/webSocket/**"
"/webSocket/**"
).
anonymous
()
).
permitAll
()
// swagger
start
// swagger
文档
.
antMatchers
(
"/swagger-ui.html"
).
permitAll
()
.
antMatchers
(
"/swagger-ui.html"
).
permitAll
()
.
antMatchers
(
"/swagger-resources/**"
).
permitAll
()
.
antMatchers
(
"/swagger-resources/**"
).
permitAll
()
.
antMatchers
(
"/webjars/**"
).
permitAll
()
.
antMatchers
(
"/webjars/**"
).
permitAll
()
.
antMatchers
(
"/*/api-docs"
).
permitAll
()
.
antMatchers
(
"/*/api-docs"
).
permitAll
()
// swagger end
// 文件
// 文件
.
antMatchers
(
"/avatar/**"
).
permitAll
()
.
antMatchers
(
"/avatar/**"
).
permitAll
()
.
antMatchers
(
"/file/**"
).
permitAll
()
.
antMatchers
(
"/file/**"
).
permitAll
()
// 阿里巴巴 druid
.
antMatchers
(
"/druid/**"
).
permitAll
()
// 放行OPTIONS请求
// 放行OPTIONS请求
.
antMatchers
(
HttpMethod
.
OPTIONS
,
"/**"
).
permitAll
()
.
antMatchers
(
HttpMethod
.
OPTIONS
,
"/**"
).
permitAll
()
.
antMatchers
(
"/druid/**"
).
permitAll
()
// 自定义匿名访问所有url放行 : 允许匿名和带权限以及登录用户访问
// 自定义匿名访问所有url放行 : 允许 匿名和带权限以及登录用户访问
.
antMatchers
(
anonymousUrls
.
toArray
(
new
String
[
0
])).
permitAll
()
.
antMatchers
(
anonymousUrls
.
toArray
(
new
String
[
0
])).
permitAll
()
// 所有请求都需要认证
// 所有请求都需要认证
.
anyRequest
().
authenticated
()
.
anyRequest
().
authenticated
()
// 防止iframe 造成跨域
.
and
().
apply
(
securityConfigurerAdapter
());
.
and
().
headers
().
frameOptions
().
disable
();
}
httpSecurity
.
addFilterBefore
(
authenticationTokenFilter
,
UsernamePasswordAuthenticationFilter
.
class
);
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;
...
@@ -8,25 +8,28 @@ import lombok.extern.slf4j.Slf4j;
import
me.zhengjie.annotation.AnonymousAccess
;
import
me.zhengjie.annotation.AnonymousAccess
;
import
me.zhengjie.aop.log.Log
;
import
me.zhengjie.aop.log.Log
;
import
me.zhengjie.exception.BadRequestException
;
import
me.zhengjie.exception.BadRequestException
;
import
me.zhengjie.modules.monitor.service.RedisService
;
import
me.zhengjie.modules.security.config.SecurityProperties
;
import
me.zhengjie.modules.security.security.AuthInfo
;
import
me.zhengjie.modules.security.security.TokenProvider
;
import
me.zhengjie.modules.security.security.AuthUser
;
import
me.zhengjie.modules.security.security.vo.AuthUser
;
import
me.zhengjie.modules.security.security.ImgResult
;
import
me.zhengjie.modules.security.security.vo.JwtUser
;
import
me.zhengjie.modules.security.security.JwtUser
;
import
me.zhengjie.modules.security.service.OnlineUserService
;
import
me.zhengjie.modules.security.service.OnlineUserService
;
import
me.zhengjie.utils.EncryptUtils
;
import
me.zhengjie.utils.RedisUtils
;
import
me.zhengjie.modules.security.utils.JwtTokenUtil
;
import
me.zhengjie.utils.SecurityUtils
;
import
me.zhengjie.utils.SecurityUtils
;
import
me.zhengjie.utils.StringUtils
;
import
me.zhengjie.utils.StringUtils
;
import
org.springframework.beans.factory.annotation.Qualifier
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.http.HttpStatus
;
import
org.springframework.http.HttpStatus
;
import
org.springframework.http.ResponseEntity
;
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.security.core.userdetails.UserDetailsService
;
import
org.springframework.validation.annotation.Validated
;
import
org.springframework.validation.annotation.Validated
;
import
org.springframework.web.bind.annotation.*
;
import
org.springframework.web.bind.annotation.*
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletRequest
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.concurrent.TimeUnit
;
/**
/**
* @author Zheng Jie
* @author Zheng Jie
...
@@ -37,24 +40,24 @@ import javax.servlet.http.HttpServletRequest;
...
@@ -37,24 +40,24 @@ import javax.servlet.http.HttpServletRequest;
@RestController
@RestController
@RequestMapping
(
"/auth"
)
@RequestMapping
(
"/auth"
)
@Api
(
tags
=
"系统:系统授权接口"
)
@Api
(
tags
=
"系统:系统授权接口"
)
public
class
AuthenticationController
{
public
class
AuthController
{
@Value
(
"${jwt.codeKey}"
)
private
String
codeKey
;
private
final
JwtTokenUtil
jwtTokenUtil
;
private
final
RedisService
redisService
;
@Value
(
"${loginCode.expiration}"
)
private
Long
expiration
;
private
final
SecurityProperties
properties
;
private
final
RedisUtils
redisUtils
;
private
final
UserDetailsService
userDetailsService
;
private
final
UserDetailsService
userDetailsService
;
private
final
OnlineUserService
onlineUserService
;
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
)
{
public
AuthController
(
SecurityProperties
properties
,
RedisUtils
redisUtils
,
UserDetailsService
userDetailsService
,
OnlineUserService
onlineUserService
,
TokenProvider
tokenProvider
,
AuthenticationManagerBuilder
authenticationManagerBuilder
)
{
this
.
jwtTokenUtil
=
jwtTokenUtil
;
this
.
properties
=
properties
;
this
.
redis
Service
=
redis
Service
;
this
.
redis
Utils
=
redis
Utils
;
this
.
userDetailsService
=
userDetailsService
;
this
.
userDetailsService
=
userDetailsService
;
this
.
onlineUserService
=
onlineUserService
;
this
.
onlineUserService
=
onlineUserService
;
this
.
tokenProvider
=
tokenProvider
;
this
.
authenticationManagerBuilder
=
authenticationManagerBuilder
;
}
}
@Log
(
"用户登录"
)
@Log
(
"用户登录"
)
...
@@ -62,32 +65,32 @@ public class AuthenticationController {
...
@@ -62,32 +65,32 @@ public class AuthenticationController {
@AnonymousAccess
@AnonymousAccess
@PostMapping
(
value
=
"/login"
)
@PostMapping
(
value
=
"/login"
)
public
ResponseEntity
login
(
@Validated
@RequestBody
AuthUser
authUser
,
HttpServletRequest
request
){
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
))
{
if
(
StringUtils
.
isBlank
(
code
))
{
throw
new
BadRequestException
(
"验证码已过期"
);
throw
new
BadRequestException
(
"验证码
不存在或
已过期"
);
}
}
if
(
StringUtils
.
isBlank
(
authUser
.
getCode
())
||
!
authUser
.
getCode
().
equalsIgnoreCase
(
code
))
{
if
(
StringUtils
.
isBlank
(
authUser
.
getCode
())
||
!
authUser
.
getCode
().
equalsIgnoreCase
(
code
))
{
throw
new
BadRequestException
(
"验证码错误"
);
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
()))){
Authentication
authentication
=
authenticationManagerBuilder
.
getObject
().
authenticate
(
authenticationToken
);
throw
new
AccountExpiredException
(
"密码错误"
);
SecurityContextHolder
.
getContext
().
setAuthentication
(
authentication
);
}
if
(!
jwtUser
.
isEnabled
()){
throw
new
AccountExpiredException
(
"账号已停用,请联系管理员"
);
}
// 生成令牌
// 生成令牌
final
String
token
=
jwtTokenUtil
.
generateToken
(
jwtUser
);
String
token
=
tokenProvider
.
createToken
(
authentication
);
final
JwtUser
jwtUser
=
(
JwtUser
)
authentication
.
getPrincipal
();
// 保存在线信息
// 保存在线信息
onlineUserService
.
save
(
jwtUser
,
token
,
request
);
onlineUserService
.
save
(
jwtUser
,
token
,
request
);
// 返回 token
// 返回 token 与 用户信息
return
ResponseEntity
.
ok
(
new
AuthInfo
(
token
,
jwtUser
));
Map
<
String
,
Object
>
authInfo
=
new
HashMap
<
String
,
Object
>(
2
){{
put
(
"token"
,
properties
.
getTokenStartWith
()
+
token
);
put
(
"user"
,
jwtUser
);
}};
return
ResponseEntity
.
ok
(
authInfo
);
}
}
@ApiOperation
(
"获取用户信息"
)
@ApiOperation
(
"获取用户信息"
)
...
@@ -97,26 +100,32 @@ public class AuthenticationController {
...
@@ -97,26 +100,32 @@ public class AuthenticationController {
return
ResponseEntity
.
ok
(
jwtUser
);
return
ResponseEntity
.
ok
(
jwtUser
);
}
}
@ApiOperation
(
"获取验证码"
)
@AnonymousAccess
@AnonymousAccess
@ApiOperation
(
"获取验证码"
)
@GetMapping
(
value
=
"/code"
)
@GetMapping
(
value
=
"/code"
)
public
ImgResult
getCode
(){
public
ResponseEntity
getCode
(){
// 算术类型 https://gitee.com/whvse/EasyCaptcha
// 算术类型 https://gitee.com/whvse/EasyCaptcha
ArithmeticCaptcha
captcha
=
new
ArithmeticCaptcha
(
111
,
36
);
ArithmeticCaptcha
captcha
=
new
ArithmeticCaptcha
(
111
,
36
);
// 几位数运算,默认是两位
// 几位数运算,默认是两位
captcha
.
setLen
(
2
);
captcha
.
setLen
(
2
);
// 获取运算的结果
:5
// 获取运算的结果
String
result
=
captcha
.
text
();
String
result
=
captcha
.
text
();
String
uuid
=
codeKey
+
IdUtil
.
simpleUUID
();
String
uuid
=
properties
.
getCodeKey
()
+
IdUtil
.
simpleUUID
();
redisService
.
saveCode
(
uuid
,
result
);
// 保存
return
new
ImgResult
(
captcha
.
toBase64
(),
uuid
);
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
(
"退出登录"
)
@ApiOperation
(
"退出登录"
)
@AnonymousAccess
@AnonymousAccess
@DeleteMapping
(
value
=
"/logout"
)
@DeleteMapping
(
value
=
"/logout"
)
public
ResponseEntity
logout
(
HttpServletRequest
request
){
public
ResponseEntity
logout
(
HttpServletRequest
request
){
onlineUserService
.
logout
(
jwtTokenUtil
.
getToken
(
request
));
onlineUserService
.
logout
(
tokenProvider
.
getToken
(
request
));
return
new
ResponseEntity
(
HttpStatus
.
OK
);
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