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
fd9fb2a6
"eladmin-common/vscode:/vscode.git/clone" did not exist on "e1c434b8543bc9b0ee094977268989706eaa97a5"
Commit
fd9fb2a6
authored
Nov 01, 2019
by
dqjdda
Browse files
Merge branch '2.3dev'
parents
7895e547
1839ef8d
Changes
227
Hide whitespace changes
Inline
Side-by-side
eladmin-system/src/main/java/me/zhengjie/modules/quartz/service/QuartzJobService.java
View file @
fd9fb2a6
...
@@ -3,76 +3,47 @@ package me.zhengjie.modules.quartz.service;
...
@@ -3,76 +3,47 @@ package me.zhengjie.modules.quartz.service;
import
me.zhengjie.modules.quartz.domain.QuartzJob
;
import
me.zhengjie.modules.quartz.domain.QuartzJob
;
import
me.zhengjie.modules.quartz.domain.QuartzLog
;
import
me.zhengjie.modules.quartz.domain.QuartzLog
;
import
me.zhengjie.modules.quartz.service.dto.JobQueryCriteria
;
import
me.zhengjie.modules.quartz.service.dto.JobQueryCriteria
;
import
org.springframework.cache.annotation.CacheConfig
;
import
org.springframework.cache.annotation.CacheEvict
;
import
org.springframework.cache.annotation.Cacheable
;
import
org.springframework.data.domain.Pageable
;
import
org.springframework.data.domain.Pageable
;
import
javax.servlet.http.HttpServletResponse
;
import
java.io.IOException
;
import
java.util.List
;
/**
/**
* @author Zheng Jie
* @author Zheng Jie
* @date 2019-01-07
* @date 2019-01-07
*/
*/
@CacheConfig
(
cacheNames
=
"quartzJob"
)
public
interface
QuartzJobService
{
public
interface
QuartzJobService
{
/**
* queryAll quartzJob
* @param criteria
* @param pageable
* @return
*/
@Cacheable
Object
queryAll
(
JobQueryCriteria
criteria
,
Pageable
pageable
);
Object
queryAll
(
JobQueryCriteria
criteria
,
Pageable
pageable
);
/**
List
<
QuartzJob
>
queryAll
(
JobQueryCriteria
criteria
);
* queryAll quartzLog
* @param criteria
* @param pageable
* @return
*/
Object
queryAllLog
(
JobQueryCriteria
criteria
,
Pageable
pageable
);
Object
queryAllLog
(
JobQueryCriteria
criteria
,
Pageable
pageable
);
/**
List
<
QuartzLog
>
queryAllLog
(
JobQueryCriteria
criteria
);
* create
* @param resources
* @return
*/
@CacheEvict
(
allEntries
=
true
)
QuartzJob
create
(
QuartzJob
resources
);
QuartzJob
create
(
QuartzJob
resources
);
/**
* update
* @param resources
* @return
*/
@CacheEvict
(
allEntries
=
true
)
void
update
(
QuartzJob
resources
);
void
update
(
QuartzJob
resources
);
/**
* del
* @param quartzJob
*/
@CacheEvict
(
allEntries
=
true
)
void
delete
(
QuartzJob
quartzJob
);
void
delete
(
QuartzJob
quartzJob
);
/**
* findById
* @param id
* @return
*/
@Cacheable
(
key
=
"#p0"
)
QuartzJob
findById
(
Long
id
);
QuartzJob
findById
(
Long
id
);
/**
/**
* 更改定时任务状态
* 更改定时任务状态
* @param quartzJob
* @param quartzJob
/
*/
*/
@CacheEvict
(
allEntries
=
true
)
void
updateIsPause
(
QuartzJob
quartzJob
);
void
updateIsPause
(
QuartzJob
quartzJob
);
/**
/**
* 立即执行定时任务
* 立即执行定时任务
* @param quartzJob
* @param quartzJob
/
*/
*/
void
execution
(
QuartzJob
quartzJob
);
void
execution
(
QuartzJob
quartzJob
);
void
download
(
List
<
QuartzJob
>
queryAll
,
HttpServletResponse
response
)
throws
IOException
;
void
downloadLog
(
List
<
QuartzLog
>
queryAllLog
,
HttpServletResponse
response
)
throws
IOException
;
}
}
eladmin-system/src/main/java/me/zhengjie/modules/quartz/service/dto/JobQueryCriteria.java
View file @
fd9fb2a6
...
@@ -3,6 +3,8 @@ package me.zhengjie.modules.quartz.service.dto;
...
@@ -3,6 +3,8 @@ package me.zhengjie.modules.quartz.service.dto;
import
lombok.Data
;
import
lombok.Data
;
import
me.zhengjie.annotation.Query
;
import
me.zhengjie.annotation.Query
;
import
java.sql.Timestamp
;
/**
/**
* @author Zheng Jie
* @author Zheng Jie
* @date 2019-6-4 10:33:02
* @date 2019-6-4 10:33:02
...
@@ -15,4 +17,10 @@ public class JobQueryCriteria {
...
@@ -15,4 +17,10 @@ public class JobQueryCriteria {
@Query
@Query
private
Boolean
isSuccess
;
private
Boolean
isSuccess
;
@Query
(
type
=
Query
.
Type
.
GREATER_THAN
,
propName
=
"createTime"
)
private
Timestamp
startTime
;
@Query
(
type
=
Query
.
Type
.
LESS_THAN
,
propName
=
"createTime"
)
private
Timestamp
endTime
;
}
}
eladmin-system/src/main/java/me/zhengjie/modules/quartz/service/impl/QuartzJobServiceImpl.java
View file @
fd9fb2a6
...
@@ -2,40 +2,55 @@ package me.zhengjie.modules.quartz.service.impl;
...
@@ -2,40 +2,55 @@ package me.zhengjie.modules.quartz.service.impl;
import
me.zhengjie.exception.BadRequestException
;
import
me.zhengjie.exception.BadRequestException
;
import
me.zhengjie.modules.quartz.domain.QuartzJob
;
import
me.zhengjie.modules.quartz.domain.QuartzJob
;
import
me.zhengjie.modules.quartz.domain.QuartzLog
;
import
me.zhengjie.modules.quartz.repository.QuartzJobRepository
;
import
me.zhengjie.modules.quartz.repository.QuartzJobRepository
;
import
me.zhengjie.modules.quartz.repository.QuartzLogRepository
;
import
me.zhengjie.modules.quartz.repository.QuartzLogRepository
;
import
me.zhengjie.modules.quartz.service.QuartzJobService
;
import
me.zhengjie.modules.quartz.service.QuartzJobService
;
import
me.zhengjie.modules.quartz.service.dto.JobQueryCriteria
;
import
me.zhengjie.modules.quartz.service.dto.JobQueryCriteria
;
import
me.zhengjie.modules.quartz.utils.QuartzManage
;
import
me.zhengjie.modules.quartz.utils.QuartzManage
;
import
me.zhengjie.utils.FileUtil
;
import
me.zhengjie.utils.PageUtil
;
import
me.zhengjie.utils.PageUtil
;
import
me.zhengjie.utils.QueryHelp
;
import
me.zhengjie.utils.QueryHelp
;
import
me.zhengjie.utils.ValidationUtil
;
import
me.zhengjie.utils.ValidationUtil
;
import
org.quartz.CronExpression
;
import
org.quartz.CronExpression
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.cache.annotation.CacheConfig
;
import
org.springframework.cache.annotation.CacheEvict
;
import
org.springframework.cache.annotation.Cacheable
;
import
org.springframework.data.domain.Pageable
;
import
org.springframework.data.domain.Pageable
;
import
org.springframework.stereotype.Service
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Propagation
;
import
org.springframework.transaction.annotation.Propagation
;
import
org.springframework.transaction.annotation.Transactional
;
import
org.springframework.transaction.annotation.Transactional
;
import
java.util.Optional
;
import
javax.servlet.http.HttpServletResponse
;
import
java.io.IOException
;
import
java.util.ArrayList
;
import
java.util.LinkedHashMap
;
import
java.util.List
;
import
java.util.Map
;
/**
/**
* @author Zheng Jie
* @author Zheng Jie
* @date 2019-01-07
* @date 2019-01-07
*/
*/
@Service
(
value
=
"quartzJobService"
)
@Service
(
value
=
"quartzJobService"
)
@CacheConfig
(
cacheNames
=
"quartzJob"
)
@Transactional
(
propagation
=
Propagation
.
SUPPORTS
,
readOnly
=
true
,
rollbackFor
=
Exception
.
class
)
@Transactional
(
propagation
=
Propagation
.
SUPPORTS
,
readOnly
=
true
,
rollbackFor
=
Exception
.
class
)
public
class
QuartzJobServiceImpl
implements
QuartzJobService
{
public
class
QuartzJobServiceImpl
implements
QuartzJobService
{
@Autowired
private
final
QuartzJobRepository
quartzJobRepository
;
private
QuartzJobRepository
quartzJobRepository
;
private
final
QuartzLogRepository
quartzLogRepository
;
@Autowired
private
final
QuartzManage
quartzManage
;
private
QuartzLogRepository
quartzLogRepository
;
@Autowired
public
QuartzJobServiceImpl
(
QuartzJobRepository
quartzJobRepository
,
QuartzLogRepository
quartzLogRepository
,
QuartzManage
quartzManage
)
{
private
QuartzManage
quartzManage
;
this
.
quartzJobRepository
=
quartzJobRepository
;
this
.
quartzLogRepository
=
quartzLogRepository
;
this
.
quartzManage
=
quartzManage
;
}
@Override
@Override
@Cacheable
public
Object
queryAll
(
JobQueryCriteria
criteria
,
Pageable
pageable
){
public
Object
queryAll
(
JobQueryCriteria
criteria
,
Pageable
pageable
){
return
PageUtil
.
toPage
(
quartzJobRepository
.
findAll
((
root
,
criteriaQuery
,
criteriaBuilder
)
->
QueryHelp
.
getPredicate
(
root
,
criteria
,
criteriaBuilder
),
pageable
));
return
PageUtil
.
toPage
(
quartzJobRepository
.
findAll
((
root
,
criteriaQuery
,
criteriaBuilder
)
->
QueryHelp
.
getPredicate
(
root
,
criteria
,
criteriaBuilder
),
pageable
));
}
}
...
@@ -46,13 +61,25 @@ public class QuartzJobServiceImpl implements QuartzJobService {
...
@@ -46,13 +61,25 @@ public class QuartzJobServiceImpl implements QuartzJobService {
}
}
@Override
@Override
public
List
<
QuartzJob
>
queryAll
(
JobQueryCriteria
criteria
)
{
return
quartzJobRepository
.
findAll
((
root
,
criteriaQuery
,
criteriaBuilder
)
->
QueryHelp
.
getPredicate
(
root
,
criteria
,
criteriaBuilder
));
}
@Override
public
List
<
QuartzLog
>
queryAllLog
(
JobQueryCriteria
criteria
)
{
return
quartzLogRepository
.
findAll
((
root
,
criteriaQuery
,
criteriaBuilder
)
->
QueryHelp
.
getPredicate
(
root
,
criteria
,
criteriaBuilder
));
}
@Override
@Cacheable
(
key
=
"#p0"
)
public
QuartzJob
findById
(
Long
id
)
{
public
QuartzJob
findById
(
Long
id
)
{
Optional
<
QuartzJob
>
quartzJob
=
quartzJobRepository
.
findById
(
id
);
QuartzJob
quartzJob
=
quartzJobRepository
.
findById
(
id
)
.
orElseGet
(
QuartzJob:
:
new
)
;
ValidationUtil
.
isNull
(
quartzJob
,
"QuartzJob"
,
"id"
,
id
);
ValidationUtil
.
isNull
(
quartzJob
.
getId
()
,
"QuartzJob"
,
"id"
,
id
);
return
quartzJob
.
get
()
;
return
quartzJob
;
}
}
@Override
@Override
@CacheEvict
(
allEntries
=
true
)
@Transactional
(
rollbackFor
=
Exception
.
class
)
@Transactional
(
rollbackFor
=
Exception
.
class
)
public
QuartzJob
create
(
QuartzJob
resources
)
{
public
QuartzJob
create
(
QuartzJob
resources
)
{
if
(!
CronExpression
.
isValidExpression
(
resources
.
getCronExpression
())){
if
(!
CronExpression
.
isValidExpression
(
resources
.
getCronExpression
())){
...
@@ -64,6 +91,7 @@ public class QuartzJobServiceImpl implements QuartzJobService {
...
@@ -64,6 +91,7 @@ public class QuartzJobServiceImpl implements QuartzJobService {
}
}
@Override
@Override
@CacheEvict
(
allEntries
=
true
)
@Transactional
(
rollbackFor
=
Exception
.
class
)
@Transactional
(
rollbackFor
=
Exception
.
class
)
public
void
update
(
QuartzJob
resources
)
{
public
void
update
(
QuartzJob
resources
)
{
if
(
resources
.
getId
().
equals
(
1L
)){
if
(
resources
.
getId
().
equals
(
1L
)){
...
@@ -77,6 +105,7 @@ public class QuartzJobServiceImpl implements QuartzJobService {
...
@@ -77,6 +105,7 @@ public class QuartzJobServiceImpl implements QuartzJobService {
}
}
@Override
@Override
@CacheEvict
(
allEntries
=
true
)
public
void
updateIsPause
(
QuartzJob
quartzJob
)
{
public
void
updateIsPause
(
QuartzJob
quartzJob
)
{
if
(
quartzJob
.
getId
().
equals
(
1L
)){
if
(
quartzJob
.
getId
().
equals
(
1L
)){
throw
new
BadRequestException
(
"该任务不可操作"
);
throw
new
BadRequestException
(
"该任务不可操作"
);
...
@@ -100,6 +129,7 @@ public class QuartzJobServiceImpl implements QuartzJobService {
...
@@ -100,6 +129,7 @@ public class QuartzJobServiceImpl implements QuartzJobService {
}
}
@Override
@Override
@CacheEvict
(
allEntries
=
true
)
@Transactional
(
rollbackFor
=
Exception
.
class
)
@Transactional
(
rollbackFor
=
Exception
.
class
)
public
void
delete
(
QuartzJob
quartzJob
)
{
public
void
delete
(
QuartzJob
quartzJob
)
{
if
(
quartzJob
.
getId
().
equals
(
1L
)){
if
(
quartzJob
.
getId
().
equals
(
1L
)){
...
@@ -108,4 +138,41 @@ public class QuartzJobServiceImpl implements QuartzJobService {
...
@@ -108,4 +138,41 @@ public class QuartzJobServiceImpl implements QuartzJobService {
quartzManage
.
deleteJob
(
quartzJob
);
quartzManage
.
deleteJob
(
quartzJob
);
quartzJobRepository
.
delete
(
quartzJob
);
quartzJobRepository
.
delete
(
quartzJob
);
}
}
@Override
public
void
download
(
List
<
QuartzJob
>
quartzJobs
,
HttpServletResponse
response
)
throws
IOException
{
List
<
Map
<
String
,
Object
>>
list
=
new
ArrayList
<>();
for
(
QuartzJob
quartzJob
:
quartzJobs
)
{
Map
<
String
,
Object
>
map
=
new
LinkedHashMap
<>();
map
.
put
(
"任务名称"
,
quartzJob
.
getJobName
());
map
.
put
(
"Bean名称"
,
quartzJob
.
getBeanName
());
map
.
put
(
"执行方法"
,
quartzJob
.
getMethodName
());
map
.
put
(
"参数"
,
quartzJob
.
getParams
());
map
.
put
(
"表达式"
,
quartzJob
.
getCronExpression
());
map
.
put
(
"状态"
,
quartzJob
.
getIsPause
()
?
"暂停中"
:
"运行中"
);
map
.
put
(
"描述"
,
quartzJob
.
getRemark
());
map
.
put
(
"创建日期"
,
quartzJob
.
getCreateTime
());
list
.
add
(
map
);
}
FileUtil
.
downloadExcel
(
list
,
response
);
}
@Override
public
void
downloadLog
(
List
<
QuartzLog
>
queryAllLog
,
HttpServletResponse
response
)
throws
IOException
{
List
<
Map
<
String
,
Object
>>
list
=
new
ArrayList
<>();
for
(
QuartzLog
quartzLog
:
queryAllLog
)
{
Map
<
String
,
Object
>
map
=
new
LinkedHashMap
<>();
map
.
put
(
"任务名称"
,
quartzLog
.
getJobName
());
map
.
put
(
"Bean名称"
,
quartzLog
.
getBeanName
());
map
.
put
(
"执行方法"
,
quartzLog
.
getMethodName
());
map
.
put
(
"参数"
,
quartzLog
.
getParams
());
map
.
put
(
"表达式"
,
quartzLog
.
getCronExpression
());
map
.
put
(
"异常详情"
,
quartzLog
.
getExceptionDetail
());
map
.
put
(
"耗时/毫秒"
,
quartzLog
.
getTime
());
map
.
put
(
"状态"
,
quartzLog
.
getIsSuccess
()
?
"成功"
:
"失败"
);
map
.
put
(
"创建日期"
,
quartzLog
.
getCreateTime
());
list
.
add
(
map
);
}
FileUtil
.
downloadExcel
(
list
,
response
);
}
}
}
eladmin-system/src/main/java/me/zhengjie/modules/quartz/task/TestTask.java
View file @
fd9fb2a6
package
me.zhengjie.modules.quartz.task
;
package
me.zhengjie.modules.quartz.task
;
import
lombok.extern.slf4j.Slf4j
;
import
lombok.extern.slf4j.Slf4j
;
import
me.zhengjie.exception.BadRequestException
;
import
org.springframework.stereotype.Component
;
import
org.springframework.stereotype.Component
;
/**
/**
...
...
eladmin-system/src/main/java/me/zhengjie/modules/quartz/task/VisitsTask.java
View file @
fd9fb2a6
package
me.zhengjie.modules.quartz.task
;
package
me.zhengjie.modules.quartz.task
;
import
me.zhengjie.modules.monitor.service.VisitsService
;
import
me.zhengjie.modules.monitor.service.VisitsService
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Component
;
import
org.springframework.stereotype.Component
;
/**
/**
...
@@ -11,8 +10,11 @@ import org.springframework.stereotype.Component;
...
@@ -11,8 +10,11 @@ import org.springframework.stereotype.Component;
@Component
@Component
public
class
VisitsTask
{
public
class
VisitsTask
{
@Autowired
private
final
VisitsService
visitsService
;
private
VisitsService
visitsService
;
public
VisitsTask
(
VisitsService
visitsService
)
{
this
.
visitsService
=
visitsService
;
}
public
void
run
(){
public
void
run
(){
visitsService
.
save
();
visitsService
.
save
();
...
...
eladmin-system/src/main/java/me/zhengjie/modules/quartz/utils/ExecutionJob.java
View file @
fd9fb2a6
package
me.zhengjie.modules.quartz.utils
;
package
me.zhengjie.modules.quartz.utils
;
import
me.zhengjie.config.thread.TheadFactoryName
;
import
me.zhengjie.config.thread.ThreadPoolExecutorUtil
;
import
me.zhengjie.modules.quartz.domain.QuartzJob
;
import
me.zhengjie.modules.quartz.domain.QuartzJob
;
import
me.zhengjie.modules.quartz.domain.QuartzLog
;
import
me.zhengjie.modules.quartz.domain.QuartzLog
;
import
me.zhengjie.modules.quartz.repository.QuartzLogRepository
;
import
me.zhengjie.modules.quartz.repository.QuartzLogRepository
;
...
@@ -11,13 +13,11 @@ import org.slf4j.Logger;
...
@@ -11,13 +13,11 @@ import org.slf4j.Logger;
import
org.slf4j.LoggerFactory
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.scheduling.annotation.Async
;
import
org.springframework.scheduling.annotation.Async
;
import
org.springframework.scheduling.quartz.QuartzJobBean
;
import
org.springframework.scheduling.quartz.QuartzJobBean
;
import
java.util.concurrent.ExecutorService
;
import
java.util.concurrent.*
;
import
java.util.concurrent.Executors
;
import
java.util.concurrent.Future
;
/**
/**
* 参考人人开源,https://gitee.com/renrenio/renren-security
* 参考人人开源,https://gitee.com/renrenio/renren-security
* @author
* @author
/
* @date 2019-01-07
* @date 2019-01-07
*/
*/
@Async
@Async
...
@@ -25,16 +25,16 @@ public class ExecutionJob extends QuartzJobBean {
...
@@ -25,16 +25,16 @@ public class ExecutionJob extends QuartzJobBean {
private
Logger
logger
=
LoggerFactory
.
getLogger
(
this
.
getClass
());
private
Logger
logger
=
LoggerFactory
.
getLogger
(
this
.
getClass
());
//
建议自定义线程池实现方式,
该处仅供参考
// 该处仅供参考
private
ExecutorService
executorService
=
Executors
.
newSingle
ThreadExecutor
();
private
final
static
ThreadPoolExecutor
executor
=
Thread
Pool
Executor
Util
.
getPoll
();
@Override
@Override
@SuppressWarnings
(
"unchecked"
)
protected
void
executeInternal
(
JobExecutionContext
context
)
{
protected
void
executeInternal
(
JobExecutionContext
context
)
{
QuartzJob
quartzJob
=
(
QuartzJob
)
context
.
getMergedJobDataMap
().
get
(
QuartzJob
.
JOB_KEY
);
QuartzJob
quartzJob
=
(
QuartzJob
)
context
.
getMergedJobDataMap
().
get
(
QuartzJob
.
JOB_KEY
);
// 获取spring bean
// 获取spring bean
QuartzLogRepository
quartzLogRepository
=
SpringContextHolder
.
getBean
(
"quartzLogRepository"
);
QuartzLogRepository
quartzLogRepository
=
SpringContextHolder
.
getBean
(
QuartzLogRepository
.
class
);
QuartzJobService
quartzJobService
=
SpringContextHolder
.
getBean
(
"quartzJobService"
);
QuartzJobService
quartzJobService
=
SpringContextHolder
.
getBean
(
QuartzJobService
.
class
);
QuartzManage
quartzManage
=
SpringContextHolder
.
getBean
(
"quartzManage"
);
QuartzLog
log
=
new
QuartzLog
();
QuartzLog
log
=
new
QuartzLog
();
log
.
setJobName
(
quartzJob
.
getJobName
());
log
.
setJobName
(
quartzJob
.
getJobName
());
...
@@ -48,7 +48,7 @@ public class ExecutionJob extends QuartzJobBean {
...
@@ -48,7 +48,7 @@ public class ExecutionJob extends QuartzJobBean {
logger
.
info
(
"任务准备执行,任务名称:{}"
,
quartzJob
.
getJobName
());
logger
.
info
(
"任务准备执行,任务名称:{}"
,
quartzJob
.
getJobName
());
QuartzRunnable
task
=
new
QuartzRunnable
(
quartzJob
.
getBeanName
(),
quartzJob
.
getMethodName
(),
QuartzRunnable
task
=
new
QuartzRunnable
(
quartzJob
.
getBeanName
(),
quartzJob
.
getMethodName
(),
quartzJob
.
getParams
());
quartzJob
.
getParams
());
Future
<?>
future
=
executor
Service
.
submit
(
task
);
Future
<?>
future
=
executor
.
submit
(
task
);
future
.
get
();
future
.
get
();
long
times
=
System
.
currentTimeMillis
()
-
startTime
;
long
times
=
System
.
currentTimeMillis
()
-
startTime
;
log
.
setTime
(
times
);
log
.
setTime
(
times
);
...
...
eladmin-system/src/main/java/me/zhengjie/modules/quartz/utils/QuartzManage.java
View file @
fd9fb2a6
...
@@ -56,8 +56,7 @@ public class QuartzManage {
...
@@ -56,8 +56,7 @@ public class QuartzManage {
/**
/**
* 更新job cron表达式
* 更新job cron表达式
* @param quartzJob
* @param quartzJob /
* @throws SchedulerException
*/
*/
public
void
updateJobCron
(
QuartzJob
quartzJob
){
public
void
updateJobCron
(
QuartzJob
quartzJob
){
try
{
try
{
...
@@ -88,8 +87,7 @@ public class QuartzManage {
...
@@ -88,8 +87,7 @@ public class QuartzManage {
/**
/**
* 删除一个job
* 删除一个job
* @param quartzJob
* @param quartzJob /
* @throws SchedulerException
*/
*/
public
void
deleteJob
(
QuartzJob
quartzJob
){
public
void
deleteJob
(
QuartzJob
quartzJob
){
try
{
try
{
...
@@ -104,8 +102,7 @@ public class QuartzManage {
...
@@ -104,8 +102,7 @@ public class QuartzManage {
/**
/**
* 恢复一个job
* 恢复一个job
* @param quartzJob
* @param quartzJob /
* @throws SchedulerException
*/
*/
public
void
resumeJob
(
QuartzJob
quartzJob
){
public
void
resumeJob
(
QuartzJob
quartzJob
){
try
{
try
{
...
@@ -124,8 +121,7 @@ public class QuartzManage {
...
@@ -124,8 +121,7 @@ public class QuartzManage {
/**
/**
* 立即执行job
* 立即执行job
* @param quartzJob
* @param quartzJob /
* @throws SchedulerException
*/
*/
public
void
runAJobNow
(
QuartzJob
quartzJob
){
public
void
runAJobNow
(
QuartzJob
quartzJob
){
try
{
try
{
...
@@ -146,8 +142,7 @@ public class QuartzManage {
...
@@ -146,8 +142,7 @@ public class QuartzManage {
/**
/**
* 暂停一个job
* 暂停一个job
* @param quartzJob
* @param quartzJob /
* @throws SchedulerException
*/
*/
public
void
pauseJob
(
QuartzJob
quartzJob
){
public
void
pauseJob
(
QuartzJob
quartzJob
){
try
{
try
{
...
...
eladmin-system/src/main/java/me/zhengjie/modules/quartz/utils/QuartzRunnable.java
View file @
fd9fb2a6
package
me.zhengjie.modules.quartz.utils
;
package
me.zhengjie.modules.quartz.utils
;
import
lombok.extern.slf4j.Slf4j
;
import
lombok.extern.slf4j.Slf4j
;
import
me.zhengjie.exception.BadRequestException
;
import
me.zhengjie.utils.SpringContextHolder
;
import
me.zhengjie.utils.SpringContextHolder
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.util.ReflectionUtils
;
import
org.springframework.util.ReflectionUtils
;
...
@@ -10,7 +9,7 @@ import java.util.concurrent.Callable;
...
@@ -10,7 +9,7 @@ import java.util.concurrent.Callable;
/**
/**
* 执行定时任务
* 执行定时任务
* @author
* @author
/
*/
*/
@Slf4j
@Slf4j
public
class
QuartzRunnable
implements
Callable
{
public
class
QuartzRunnable
implements
Callable
{
...
...
eladmin-system/src/main/java/me/zhengjie/modules/security/config/SecurityConfig.java
View file @
fd9fb2a6
package
me.zhengjie.modules.security.config
;
package
me.zhengjie.modules.security.config
;
import
me.zhengjie.annotation.AnonymousAccess
;
import
me.zhengjie.config.ElPermissionConfig
;
import
me.zhengjie.modules.security.security.JwtAuthenticationEntryPoint
;
import
me.zhengjie.modules.security.security.JwtAuthenticationEntryPoint
;
import
me.zhengjie.modules.security.security.JwtAuthorizationTokenFilter
;
import
me.zhengjie.modules.security.security.JwtAuthorizationTokenFilter
;
import
me.zhengjie.modules.security.service.JwtUserDetailsService
;
import
me.zhengjie.modules.security.service.JwtUserDetailsService
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.beans.factory.annotation.Value
;
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.authentication.AuthenticationManager
;
import
org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
;
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
;
...
@@ -19,29 +23,37 @@ import org.springframework.security.config.http.SessionCreationPolicy;
...
@@ -19,29 +23,37 @@ 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.method.HandlerMethod
;
import
org.springframework.web.servlet.mvc.method.RequestMappingInfo
;
import
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
;
import
java.util.HashSet
;
import
java.util.Map
;
import
java.util.Set
;
@Configuration
@Configuration
@EnableWebSecurity
@EnableWebSecurity
@EnableGlobalMethodSecurity
(
prePostEnabled
=
true
)
@EnableGlobalMethodSecurity
(
prePostEnabled
=
true
)
public
class
SecurityConfig
extends
WebSecurityConfigurerAdapter
{
public
class
SecurityConfig
extends
WebSecurityConfigurerAdapter
{
@Autowired
private
final
JwtAuthenticationEntryPoint
unauthorizedHandler
;
private
JwtAuthenticationEntryPoint
unauthorizedHandler
;
@Autowired
private
final
JwtUserDetailsService
jwtUserDetailsService
;
private
JwtUserDetailsService
jwtUserDetailsService
;
/**
private
final
ApplicationContext
applicationContext
;
* 自定义基于JWT的安全过滤器
*/
// 自定义基于JWT的安全过滤器
@Autowired
private
final
JwtAuthorizationTokenFilter
authenticationTokenFilter
;
JwtAuthorizationTokenFilter
authenticationTokenFilter
;
@Value
(
"${jwt.header}"
)
@Value
(
"${jwt.header}"
)
private
String
tokenHeader
;
private
String
tokenHeader
;
@Value
(
"${jwt.auth.path}"
)
public
SecurityConfig
(
JwtAuthenticationEntryPoint
unauthorizedHandler
,
JwtUserDetailsService
jwtUserDetailsService
,
JwtAuthorizationTokenFilter
authenticationTokenFilter
,
ApplicationContext
applicationContext
)
{
private
String
loginPath
;
this
.
unauthorizedHandler
=
unauthorizedHandler
;
this
.
jwtUserDetailsService
=
jwtUserDetailsService
;
this
.
authenticationTokenFilter
=
authenticationTokenFilter
;
this
.
applicationContext
=
applicationContext
;
}
@Autowired
@Autowired
public
void
configureGlobal
(
AuthenticationManagerBuilder
auth
)
throws
Exception
{
public
void
configureGlobal
(
AuthenticationManagerBuilder
auth
)
throws
Exception
{
...
@@ -69,18 +81,26 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
...
@@ -69,18 +81,26 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
@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
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
().
contains
(
"anonymous"
))
{
anonymousUrls
.
addAll
(
infoEntry
.
getKey
().
getPatternsCondition
().
getPatterns
());
}
else
if
(
null
!=
anonymousAccess
&&
null
==
preAuthorize
)
{
anonymousUrls
.
addAll
(
infoEntry
.
getKey
().
getPatternsCondition
().
getPatterns
());
}
}
httpSecurity
httpSecurity
// 禁用 CSRF
// 禁用 CSRF
.
csrf
().
disable
()
.
csrf
().
disable
()
// 授权异常
// 授权异常
.
exceptionHandling
().
authenticationEntryPoint
(
unauthorizedHandler
).
and
()
.
exceptionHandling
().
authenticationEntryPoint
(
unauthorizedHandler
).
and
()
// 不创建会话
// 不创建会话
.
sessionManagement
().
sessionCreationPolicy
(
SessionCreationPolicy
.
STATELESS
).
and
()
.
sessionManagement
().
sessionCreationPolicy
(
SessionCreationPolicy
.
STATELESS
).
and
()
// 过滤请求
// 过滤请求
.
authorizeRequests
()
.
authorizeRequests
()
.
antMatchers
(
.
antMatchers
(
...
@@ -90,35 +110,24 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
...
@@ -90,35 +110,24 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
"/**/*.css"
,
"/**/*.css"
,
"/**/*.js"
"/**/*.js"
).
anonymous
()
).
anonymous
()
.
antMatchers
(
HttpMethod
.
POST
,
"/auth/"
+
loginPath
).
anonymous
()
.
antMatchers
(
"/auth/vCode"
).
anonymous
()
// 支付宝回调
.
antMatchers
(
"/api/aliPay/return"
).
anonymous
()
.
antMatchers
(
"/api/aliPay/notify"
).
anonymous
()
// swagger start
// swagger start
.
antMatchers
(
"/swagger-ui.html"
).
anonymous
()
.
antMatchers
(
"/swagger-ui.html"
).
permitAll
()
.
antMatchers
(
"/swagger-resources/**"
).
anonymous
()
.
antMatchers
(
"/swagger-resources/**"
).
permitAll
()
.
antMatchers
(
"/webjars/**"
).
anonymous
()
.
antMatchers
(
"/webjars/**"
).
permitAll
()
.
antMatchers
(
"/*/api-docs"
).
anonymous
()
.
antMatchers
(
"/*/api-docs"
).
permitAll
()
// swagger end
// swagger end
// 接口限流测试
.
antMatchers
(
"/test/**"
).
anonymous
()
// 文件
// 文件
.
antMatchers
(
"/avatar/**"
).
anonymous
()
.
antMatchers
(
"/avatar/**"
).
permitAll
()
.
antMatchers
(
"/file/**"
).
anonymous
()
.
antMatchers
(
"/file/**"
).
permitAll
()
// 放行OPTIONS请求
// 放行OPTIONS请求
.
antMatchers
(
HttpMethod
.
OPTIONS
,
"/**"
).
anonymous
()
.
antMatchers
(
HttpMethod
.
OPTIONS
,
"/**"
).
permitAll
()
.
antMatchers
(
"/druid/**"
).
permitAll
()
.
antMatchers
(
"/druid/**"
).
anonymous
()
// 自定义匿名访问所有url放行 : 允许 匿名和带权限以及登录用户访问
.
antMatchers
(
anonymousUrls
.
toArray
(
new
String
[
0
])).
permitAll
()
// 所有请求都需要认证
// 所有请求都需要认证
.
anyRequest
().
authenticated
()
.
anyRequest
().
authenticated
()
// 防止iframe 造成跨域
// 防止iframe 造成跨域
.
and
().
headers
().
frameOptions
().
disable
();
.
and
().
headers
().
frameOptions
().
disable
();
httpSecurity
httpSecurity
.
addFilterBefore
(
authenticationTokenFilter
,
UsernamePasswordAuthenticationFilter
.
class
);
.
addFilterBefore
(
authenticationTokenFilter
,
UsernamePasswordAuthenticationFilter
.
class
);
}
}
...
...
eladmin-system/src/main/java/me/zhengjie/modules/security/rest/AuthenticationController.java
View file @
fd9fb2a6
package
me.zhengjie.modules.security.rest
;
package
me.zhengjie.modules.security.rest
;
import
cn.hutool.core.codec.Base64
;
import
cn.hutool.core.util.IdUtil
;
import
cn.hutool.core.util.IdUtil
;
import
com.wf.captcha.ArithmeticCaptcha
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiOperation
;
import
lombok.extern.slf4j.Slf4j
;
import
lombok.extern.slf4j.Slf4j
;
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.monitor.service.RedisService
;
import
me.zhengjie.modules.security.security.Auth
entication
Info
;
import
me.zhengjie.modules.security.security.AuthInfo
;
import
me.zhengjie.modules.security.security.Auth
orization
User
;
import
me.zhengjie.modules.security.security.AuthUser
;
import
me.zhengjie.modules.security.security.ImgResult
;
import
me.zhengjie.modules.security.security.ImgResult
;
import
me.zhengjie.modules.security.security.JwtUser
;
import
me.zhengjie.modules.security.security.JwtUser
;
import
me.zhengjie.modules.security.
utils.VerifyCodeUtils
;
import
me.zhengjie.modules.security.
service.OnlineUserService
;
import
me.zhengjie.utils.EncryptUtils
;
import
me.zhengjie.utils.EncryptUtils
;
import
me.zhengjie.modules.security.utils.JwtTokenUtil
;
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.Autowired
;
import
org.springframework.beans.factory.annotation.Qualifier
;
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.ResponseEntity
;
import
org.springframework.http.ResponseEntity
;
import
org.springframework.security.authentication.AccountExpiredException
;
import
org.springframework.security.authentication.AccountExpiredException
;
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.HttpServletResponse
;
import
javax.servlet.http.HttpServletRequest
;
import
java.io.ByteArrayOutputStream
;
import
java.io.IOException
;
/**
/**
* @author Zheng Jie
* @author Zheng Jie
...
@@ -34,30 +35,33 @@ import java.io.IOException;
...
@@ -34,30 +35,33 @@ import java.io.IOException;
*/
*/
@Slf4j
@Slf4j
@RestController
@RestController
@RequestMapping
(
"auth"
)
@RequestMapping
(
"/auth"
)
@Api
(
tags
=
"系统:系统授权接口"
)
public
class
AuthenticationController
{
public
class
AuthenticationController
{
@Value
(
"${jwt.
header
}"
)
@Value
(
"${jwt.
codeKey
}"
)
private
String
tokenHeader
;
private
String
codeKey
;
@Autowired
private
final
JwtTokenUtil
jwtTokenUtil
;
private
JwtTokenUtil
jwtTokenUtil
;
@Autowired
private
final
RedisService
redisService
;
private
RedisService
redisService
;
@Autowired
private
final
UserDetailsService
userDetailsService
;
@Qualifier
(
"jwtUserDetailsService"
)
private
UserDetailsService
userDetailsService
;
private
final
OnlineUserService
onlineUserService
;
public
AuthenticationController
(
JwtTokenUtil
jwtTokenUtil
,
RedisService
redisService
,
@Qualifier
(
"jwtUserDetailsService"
)
UserDetailsService
userDetailsService
,
OnlineUserService
onlineUserService
)
{
this
.
jwtTokenUtil
=
jwtTokenUtil
;
this
.
redisService
=
redisService
;
this
.
userDetailsService
=
userDetailsService
;
this
.
onlineUserService
=
onlineUserService
;
}
/**
* 登录授权
* @param authorizationUser
* @return
*/
@Log
(
"用户登录"
)
@Log
(
"用户登录"
)
@PostMapping
(
value
=
"${jwt.auth.path}"
)
@ApiOperation
(
"登录授权"
)
public
ResponseEntity
login
(
@Validated
@RequestBody
AuthorizationUser
authorizationUser
){
@AnonymousAccess
@PostMapping
(
value
=
"/login"
)
public
ResponseEntity
login
(
@Validated
@RequestBody
AuthUser
authorizationUser
,
HttpServletRequest
request
){
// 查询验证码
// 查询验证码
String
code
=
redisService
.
getCodeVal
(
authorizationUser
.
getUuid
());
String
code
=
redisService
.
getCodeVal
(
authorizationUser
.
getUuid
());
...
@@ -78,45 +82,41 @@ public class AuthenticationController {
...
@@ -78,45 +82,41 @@ public class AuthenticationController {
if
(!
jwtUser
.
isEnabled
()){
if
(!
jwtUser
.
isEnabled
()){
throw
new
AccountExpiredException
(
"账号已停用,请联系管理员"
);
throw
new
AccountExpiredException
(
"账号已停用,请联系管理员"
);
}
}
// 生成令牌
// 生成令牌
final
String
token
=
jwtTokenUtil
.
generateToken
(
jwtUser
);
final
String
token
=
jwtTokenUtil
.
generateToken
(
jwtUser
);
// 保存在线信息
onlineUserService
.
save
(
jwtUser
,
token
,
request
);
// 返回 token
// 返回 token
return
ResponseEntity
.
ok
(
new
Auth
entication
Info
(
token
,
jwtUser
));
return
ResponseEntity
.
ok
(
new
AuthInfo
(
token
,
jwtUser
));
}
}
/**
@ApiOperation
(
"获取用户信息"
)
* 获取用户信息
@GetMapping
(
value
=
"/info"
)
* @return
*/
@GetMapping
(
value
=
"${jwt.auth.account}"
)
public
ResponseEntity
getUserInfo
(){
public
ResponseEntity
getUserInfo
(){
JwtUser
jwtUser
=
(
JwtUser
)
userDetailsService
.
loadUserByUsername
(
SecurityUtils
.
getUsername
());
JwtUser
jwtUser
=
(
JwtUser
)
userDetailsService
.
loadUserByUsername
(
SecurityUtils
.
getUsername
());
return
ResponseEntity
.
ok
(
jwtUser
);
return
ResponseEntity
.
ok
(
jwtUser
);
}
}
/**
@ApiOperation
(
"获取验证码"
)
* 获取验证码
@AnonymousAccess
*/
@GetMapping
(
value
=
"/code"
)
@GetMapping
(
value
=
"vCode"
)
public
ImgResult
getCode
(){
public
ImgResult
getCode
(
HttpServletResponse
response
)
throws
IOException
{
// 算术类型 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
);
}
//生成随机字串
@ApiOperation
(
"退出登录"
)
String
verifyCode
=
VerifyCodeUtils
.
generateVerifyCode
(
4
);
@AnonymousAccess
String
uuid
=
IdUtil
.
simpleUUID
();
@DeleteMapping
(
value
=
"/logout"
)
redisService
.
saveCode
(
uuid
,
verifyCode
);
public
ResponseEntity
logout
(
HttpServletRequest
request
){
// 生成图片
onlineUserService
.
logout
(
jwtTokenUtil
.
getToken
(
request
));
int
w
=
111
,
h
=
36
;
return
new
ResponseEntity
(
HttpStatus
.
OK
);
ByteArrayOutputStream
stream
=
new
ByteArrayOutputStream
();
VerifyCodeUtils
.
outputImage
(
w
,
h
,
stream
,
verifyCode
);
try
{
return
new
ImgResult
(
Base64
.
encode
(
stream
.
toByteArray
()),
uuid
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
null
;
}
finally
{
stream
.
close
();
}
}
}
}
}
eladmin-system/src/main/java/me/zhengjie/modules/security/rest/OnlineController.java
0 → 100644
View file @
fd9fb2a6
package
me.zhengjie.modules.security.rest
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiOperation
;
import
me.zhengjie.aop.log.Log
;
import
me.zhengjie.modules.security.service.OnlineUserService
;
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
;
@RestController
@RequestMapping
(
"/auth/online"
)
@Api
(
tags
=
"系统:在线用户管理"
)
public
class
OnlineController
{
private
final
OnlineUserService
onlineUserService
;
public
OnlineController
(
OnlineUserService
onlineUserService
)
{
this
.
onlineUserService
=
onlineUserService
;
}
@ApiOperation
(
"查询在线用户"
)
@GetMapping
@PreAuthorize
(
"@el.check()"
)
public
ResponseEntity
getAll
(
String
filter
,
Pageable
pageable
){
return
new
ResponseEntity
<>(
onlineUserService
.
getAll
(
filter
,
pageable
),
HttpStatus
.
OK
);
}
@Log
(
"导出数据"
)
@ApiOperation
(
"导出数据"
)
@GetMapping
(
value
=
"/download"
)
@PreAuthorize
(
"@el.check()"
)
public
void
download
(
HttpServletResponse
response
,
String
filter
)
throws
IOException
{
onlineUserService
.
download
(
onlineUserService
.
getAll
(
filter
),
response
);
}
@ApiOperation
(
"踢出用户"
)
@DeleteMapping
(
value
=
"/{key}"
)
@PreAuthorize
(
"@el.check()"
)
public
ResponseEntity
delete
(
@PathVariable
String
key
)
throws
Exception
{
onlineUserService
.
kickOut
(
key
);
return
new
ResponseEntity
(
HttpStatus
.
OK
);
}
}
eladmin-system/src/main/java/me/zhengjie/modules/security/security/Auth
entication
Info.java
→
eladmin-system/src/main/java/me/zhengjie/modules/security/security/AuthInfo.java
View file @
fd9fb2a6
package
me.zhengjie.modules.security.security
;
package
me.zhengjie.modules.security.security
;
import
lombok.AllArgsConstructor
;
import
lombok.AllArgsConstructor
;
import
lombok.Getter
;
import
lombok.Getter
;
import
java.io.Serializable
;
import
java.io.Serializable
;
/**
/**
* @author Zheng Jie
* @author Zheng Jie
* @date 2018-11-23
* @date 2018-11-23
* 返回token
* 返回token
*/
*/
@Getter
@Getter
@AllArgsConstructor
@AllArgsConstructor
public
class
Auth
entication
Info
implements
Serializable
{
public
class
AuthInfo
implements
Serializable
{
private
final
String
token
;
private
final
String
token
;
private
final
JwtUser
user
;
private
final
JwtUser
user
;
}
}
eladmin-system/src/main/java/me/zhengjie/modules/security/security/Auth
orization
User.java
→
eladmin-system/src/main/java/me/zhengjie/modules/security/security/AuthUser.java
View file @
fd9fb2a6
...
@@ -11,7 +11,7 @@ import javax.validation.constraints.NotBlank;
...
@@ -11,7 +11,7 @@ import javax.validation.constraints.NotBlank;
*/
*/
@Getter
@Getter
@Setter
@Setter
public
class
Auth
orization
User
{
public
class
AuthUser
{
@NotBlank
@NotBlank
private
String
username
;
private
String
username
;
...
...
eladmin-system/src/main/java/me/zhengjie/modules/security/security/JwtAuthenticationEntryPoint.java
View file @
fd9fb2a6
...
@@ -18,9 +18,7 @@ public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint, Se
...
@@ -18,9 +18,7 @@ public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint, Se
public
void
commence
(
HttpServletRequest
request
,
public
void
commence
(
HttpServletRequest
request
,
HttpServletResponse
response
,
HttpServletResponse
response
,
AuthenticationException
authException
)
throws
IOException
{
AuthenticationException
authException
)
throws
IOException
{
/**
// 当用户尝试访问安全的REST资源而不提供任何凭据时,将调用此方法发送401 响应
* 当用户尝试访问安全的REST资源而不提供任何凭据时,将调用此方法发送401 响应
*/
response
.
sendError
(
HttpServletResponse
.
SC_UNAUTHORIZED
,
authException
==
null
?
"Unauthorized"
:
authException
.
getMessage
());
response
.
sendError
(
HttpServletResponse
.
SC_UNAUTHORIZED
,
authException
==
null
?
"Unauthorized"
:
authException
.
getMessage
());
}
}
}
}
eladmin-system/src/main/java/me/zhengjie/modules/security/security/JwtAuthorizationTokenFilter.java
View file @
fd9fb2a6
...
@@ -3,11 +3,12 @@ package me.zhengjie.modules.security.security;
...
@@ -3,11 +3,12 @@ package me.zhengjie.modules.security.security;
import
io.jsonwebtoken.ExpiredJwtException
;
import
io.jsonwebtoken.ExpiredJwtException
;
import
lombok.extern.slf4j.Slf4j
;
import
lombok.extern.slf4j.Slf4j
;
import
me.zhengjie.modules.security.utils.JwtTokenUtil
;
import
me.zhengjie.modules.security.utils.JwtTokenUtil
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Qualifier
;
import
org.springframework.beans.factory.annotation.Qualifier
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.data.redis.core.RedisTemplate
;
import
org.springframework.security.authentication.UsernamePasswordAuthenticationToken
;
import
org.springframework.security.authentication.UsernamePasswordAuthenticationToken
;
import
org.springframework.security.core.context.SecurityContextHolder
;
import
org.springframework.security.core.context.SecurityContextHolder
;
import
org.springframework.security.core.userdetails.UserDetails
;
import
org.springframework.security.core.userdetails.UserDetailsService
;
import
org.springframework.security.core.userdetails.UserDetailsService
;
import
org.springframework.security.web.authentication.WebAuthenticationDetailsSource
;
import
org.springframework.security.web.authentication.WebAuthenticationDetailsSource
;
import
org.springframework.stereotype.Component
;
import
org.springframework.stereotype.Component
;
...
@@ -22,38 +23,33 @@ import java.io.IOException;
...
@@ -22,38 +23,33 @@ import java.io.IOException;
@Component
@Component
public
class
JwtAuthorizationTokenFilter
extends
OncePerRequestFilter
{
public
class
JwtAuthorizationTokenFilter
extends
OncePerRequestFilter
{
@Value
(
"${jwt.online}"
)
private
String
onlineKey
;
private
final
UserDetailsService
userDetailsService
;
private
final
UserDetailsService
userDetailsService
;
private
final
JwtTokenUtil
jwtTokenUtil
;
private
final
JwtTokenUtil
jwtTokenUtil
;
private
final
String
tokenHeader
;
private
final
RedisTemplate
redisTemplate
;
public
JwtAuthorizationTokenFilter
(
@Qualifier
(
"jwtUserDetailsService"
)
UserDetailsService
userDetailsService
,
JwtTokenUtil
jwtTokenUtil
,
@Value
(
"${jwt.header}"
)
String
tokenHeader
)
{
public
JwtAuthorizationTokenFilter
(
@Qualifier
(
"jwtUserDetailsService"
)
UserDetailsService
userDetailsService
,
JwtTokenUtil
jwtTokenUtil
,
RedisTemplate
redisTemplate
)
{
this
.
userDetailsService
=
userDetailsService
;
this
.
userDetailsService
=
userDetailsService
;
this
.
jwtTokenUtil
=
jwtTokenUtil
;
this
.
jwtTokenUtil
=
jwtTokenUtil
;
this
.
tokenHeader
=
tokenHeader
;
this
.
redisTemplate
=
redisTemplate
;
}
}
@Override
@Override
protected
void
doFilterInternal
(
HttpServletRequest
request
,
HttpServletResponse
response
,
FilterChain
chain
)
throws
ServletException
,
IOException
{
protected
void
doFilterInternal
(
HttpServletRequest
request
,
HttpServletResponse
response
,
FilterChain
chain
)
throws
ServletException
,
IOException
{
String
authToken
=
jwtTokenUtil
.
getToken
(
request
);
final
String
requestHeader
=
request
.
getHeader
(
this
.
tokenHeader
);
OnlineUser
onlineUser
=
null
;
try
{
String
username
=
null
;
onlineUser
=
(
OnlineUser
)
redisTemplate
.
opsForValue
().
get
(
onlineKey
+
authToken
);
String
authToken
=
null
;
}
catch
(
ExpiredJwtException
e
)
{
if
(
requestHeader
!=
null
&&
requestHeader
.
startsWith
(
"Bearer "
))
{
log
.
error
(
e
.
getMessage
());
authToken
=
requestHeader
.
substring
(
7
);
try
{
username
=
jwtTokenUtil
.
getUsernameFromToken
(
authToken
);
}
catch
(
ExpiredJwtException
e
)
{
log
.
error
(
e
.
getMessage
());
}
}
}
if
(
onlineUser
!=
null
&&
SecurityContextHolder
.
getContext
().
getAuthentication
()
==
null
)
{
if
(
username
!=
null
&&
SecurityContextHolder
.
getContext
().
getAuthentication
()
==
null
)
{
// It is not compelling necessary to load the use details from the database. You could also store the information
// It is not compelling necessary to load the use details from the database. You could also store the information
// in the token and read it from it. It's up to you ;)
// in the token and read it from it. It's up to you ;)
JwtUser
userDetails
=
(
JwtUser
)
this
.
userDetailsService
.
loadUserByUsername
(
username
);
JwtUser
userDetails
=
(
JwtUser
)
this
.
userDetailsService
.
loadUserByUsername
(
onlineUser
.
getUserName
());
// For simple validation it is completely sufficient to just check the token integrity. You don't have to call
// For simple validation it is completely sufficient to just check the token integrity. You don't have to call
// the database compellingly. Again it's up to you ;)
// the database compellingly. Again it's up to you ;)
if
(
jwtTokenUtil
.
validateToken
(
authToken
,
userDetails
))
{
if
(
jwtTokenUtil
.
validateToken
(
authToken
,
userDetails
))
{
...
...
eladmin-system/src/main/java/me/zhengjie/modules/security/security/OnlineUser.java
0 → 100644
View file @
fd9fb2a6
package
me.zhengjie.modules.security.security
;
import
lombok.AllArgsConstructor
;
import
lombok.Data
;
import
lombok.NoArgsConstructor
;
import
java.util.Date
;
/**
* @author Zheng Jie
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public
class
OnlineUser
{
private
String
userName
;
private
String
job
;
private
String
browser
;
private
String
ip
;
private
String
address
;
private
String
key
;
private
Date
loginTime
;
}
eladmin-system/src/main/java/me/zhengjie/modules/security/service/JwtPermissionService.java
View file @
fd9fb2a6
package
me.zhengjie.modules.security.service
;
package
me.zhengjie.modules.security.service
;
import
me.zhengjie.modules.system.domain.Menu
;
import
me.zhengjie.modules.system.domain.Role
;
import
me.zhengjie.modules.system.domain.Role
;
import
me.zhengjie.modules.system.repository.RoleRepository
;
import
me.zhengjie.modules.system.repository.RoleRepository
;
import
me.zhengjie.modules.system.service.dto.UserDTO
;
import
me.zhengjie.modules.system.service.dto.UserDTO
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
me.zhengjie.utils.StringUtils
;
import
org.springframework.cache.annotation.CacheConfig
;
import
org.springframework.cache.annotation.CacheConfig
;
import
org.springframework.cache.annotation.Cacheable
;
import
org.springframework.cache.annotation.Cacheable
;
import
org.springframework.security.core.GrantedAuthority
;
import
org.springframework.security.core.GrantedAuthority
;
import
org.springframework.security.core.authority.SimpleGrantedAuthority
;
import
org.springframework.security.core.authority.SimpleGrantedAuthority
;
import
org.springframework.stereotype.Service
;
import
org.springframework.stereotype.Service
;
import
java.util.Collection
;
import
java.util.Collection
;
import
java.util.List
;
import
java.util.Set
;
import
java.util.Set
;
import
java.util.stream.Collectors
;
import
java.util.stream.Collectors
;
...
@@ -17,13 +19,16 @@ import java.util.stream.Collectors;
...
@@ -17,13 +19,16 @@ import java.util.stream.Collectors;
@CacheConfig
(
cacheNames
=
"role"
)
@CacheConfig
(
cacheNames
=
"role"
)
public
class
JwtPermissionService
{
public
class
JwtPermissionService
{
@Autowired
private
final
RoleRepository
roleRepository
;
private
RoleRepository
roleRepository
;
public
JwtPermissionService
(
RoleRepository
roleRepository
)
{
this
.
roleRepository
=
roleRepository
;
}
/**
/**
* key的名称如有修改,请同步修改 UserServiceImpl 中的 update 方法
* key的名称如有修改,请同步修改 UserServiceImpl 中的 update 方法
* @param user
* @param user
用户信息
* @return
* @return
Collection
*/
*/
@Cacheable
(
key
=
"'loadPermissionByUser:' + #p0.username"
)
@Cacheable
(
key
=
"'loadPermissionByUser:' + #p0.username"
)
public
Collection
<
GrantedAuthority
>
mapToGrantedAuthorities
(
UserDTO
user
)
{
public
Collection
<
GrantedAuthority
>
mapToGrantedAuthorities
(
UserDTO
user
)
{
...
@@ -31,9 +36,13 @@ public class JwtPermissionService {
...
@@ -31,9 +36,13 @@ public class JwtPermissionService {
System
.
out
.
println
(
"--------------------loadPermissionByUser:"
+
user
.
getUsername
()
+
"---------------------"
);
System
.
out
.
println
(
"--------------------loadPermissionByUser:"
+
user
.
getUsername
()
+
"---------------------"
);
Set
<
Role
>
roles
=
roleRepository
.
findByUsers_Id
(
user
.
getId
());
Set
<
Role
>
roles
=
roleRepository
.
findByUsers_Id
(
user
.
getId
());
Set
<
String
>
permissions
=
roles
.
stream
().
filter
(
role
->
StringUtils
.
isNotBlank
(
role
.
getPermission
())).
map
(
Role:
:
getPermission
).
collect
(
Collectors
.
toSet
());
return
roles
.
stream
().
flatMap
(
role
->
role
.
getPermissions
().
stream
())
permissions
.
addAll
(
.
map
(
permission
->
new
SimpleGrantedAuthority
(
permission
.
getName
()))
roles
.
stream
().
flatMap
(
role
->
role
.
getMenus
().
stream
())
.
filter
(
menu
->
StringUtils
.
isNotBlank
(
menu
.
getPermission
()))
.
map
(
Menu:
:
getPermission
).
collect
(
Collectors
.
toSet
())
);
return
permissions
.
stream
().
map
(
permission
->
new
SimpleGrantedAuthority
(
permission
))
.
collect
(
Collectors
.
toList
());
.
collect
(
Collectors
.
toList
());
}
}
}
}
eladmin-system/src/main/java/me/zhengjie/modules/security/service/JwtUserDetailsService.java
View file @
fd9fb2a6
...
@@ -4,7 +4,6 @@ import me.zhengjie.exception.BadRequestException;
...
@@ -4,7 +4,6 @@ import me.zhengjie.exception.BadRequestException;
import
me.zhengjie.modules.security.security.JwtUser
;
import
me.zhengjie.modules.security.security.JwtUser
;
import
me.zhengjie.modules.system.service.UserService
;
import
me.zhengjie.modules.system.service.UserService
;
import
me.zhengjie.modules.system.service.dto.*
;
import
me.zhengjie.modules.system.service.dto.*
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.security.core.userdetails.UserDetails
;
import
org.springframework.security.core.userdetails.UserDetails
;
import
org.springframework.security.core.userdetails.UserDetailsService
;
import
org.springframework.security.core.userdetails.UserDetailsService
;
import
org.springframework.stereotype.Service
;
import
org.springframework.stereotype.Service
;
...
@@ -20,11 +19,14 @@ import java.util.Optional;
...
@@ -20,11 +19,14 @@ import java.util.Optional;
@Transactional
(
propagation
=
Propagation
.
SUPPORTS
,
readOnly
=
true
,
rollbackFor
=
Exception
.
class
)
@Transactional
(
propagation
=
Propagation
.
SUPPORTS
,
readOnly
=
true
,
rollbackFor
=
Exception
.
class
)
public
class
JwtUserDetailsService
implements
UserDetailsService
{
public
class
JwtUserDetailsService
implements
UserDetailsService
{
@Autowired
private
final
UserService
userService
;
private
UserService
userService
;
@Autowired
private
final
JwtPermissionService
permissionService
;
private
JwtPermissionService
permissionService
;
public
JwtUserDetailsService
(
UserService
userService
,
JwtPermissionService
permissionService
)
{
this
.
userService
=
userService
;
this
.
permissionService
=
permissionService
;
}
@Override
@Override
public
UserDetails
loadUserByUsername
(
String
username
){
public
UserDetails
loadUserByUsername
(
String
username
){
...
...
eladmin-system/src/main/java/me/zhengjie/modules/security/service/OnlineUserService.java
0 → 100644
View file @
fd9fb2a6
package
me.zhengjie.modules.security.service
;
import
me.zhengjie.modules.security.security.JwtUser
;
import
me.zhengjie.modules.security.security.OnlineUser
;
import
me.zhengjie.utils.EncryptUtils
;
import
me.zhengjie.utils.FileUtil
;
import
me.zhengjie.utils.PageUtil
;
import
me.zhengjie.utils.StringUtils
;
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.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
java.io.IOException
;
import
java.util.*
;
import
java.util.concurrent.TimeUnit
;
/**
* @author Zheng Jie
* @Date 2019年10月26日21:56:27
*/
@Service
@SuppressWarnings
({
"unchecked"
,
"all"
})
public
class
OnlineUserService
{
@Value
(
"${jwt.expiration}"
)
private
Long
expiration
;
@Value
(
"${jwt.online}"
)
private
String
onlineKey
;
private
final
RedisTemplate
redisTemplate
;
public
OnlineUserService
(
RedisTemplate
redisTemplate
)
{
this
.
redisTemplate
=
redisTemplate
;
}
public
void
save
(
JwtUser
jwtUser
,
String
token
,
HttpServletRequest
request
){
String
job
=
jwtUser
.
getDept
()
+
"/"
+
jwtUser
.
getJob
();
String
ip
=
StringUtils
.
getIp
(
request
);
String
browser
=
StringUtils
.
getBrowser
(
request
);
String
address
=
StringUtils
.
getCityInfo
(
ip
);
OnlineUser
onlineUser
=
null
;
try
{
onlineUser
=
new
OnlineUser
(
jwtUser
.
getUsername
(),
job
,
browser
,
ip
,
address
,
EncryptUtils
.
desEncrypt
(
token
),
new
Date
());
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
redisTemplate
.
opsForValue
().
set
(
onlineKey
+
token
,
onlineUser
);
redisTemplate
.
expire
(
onlineKey
+
token
,
expiration
,
TimeUnit
.
MILLISECONDS
);
}
public
Page
<
OnlineUser
>
getAll
(
String
filter
,
Pageable
pageable
){
List
<
OnlineUser
>
onlineUsers
=
getAll
(
filter
);
return
new
PageImpl
<
OnlineUser
>(
PageUtil
.
toPage
(
pageable
.
getPageNumber
(),
pageable
.
getPageSize
(),
onlineUsers
),
pageable
,
onlineUsers
.
size
());
}
public
List
<
OnlineUser
>
getAll
(
String
filter
){
List
<
String
>
keys
=
new
ArrayList
<>(
redisTemplate
.
keys
(
onlineKey
+
"*"
));
Collections
.
reverse
(
keys
);
List
<
OnlineUser
>
onlineUsers
=
new
ArrayList
<>();
for
(
String
key
:
keys
)
{
OnlineUser
onlineUser
=
(
OnlineUser
)
redisTemplate
.
opsForValue
().
get
(
key
);
if
(
StringUtils
.
isNotBlank
(
filter
)){
if
(
onlineUser
.
toString
().
contains
(
filter
)){
onlineUsers
.
add
(
onlineUser
);
}
}
else
{
onlineUsers
.
add
(
onlineUser
);
}
}
Collections
.
sort
(
onlineUsers
,
(
o1
,
o2
)
->
{
return
o2
.
getLoginTime
().
compareTo
(
o1
.
getLoginTime
());
});
return
onlineUsers
;
}
public
void
kickOut
(
String
val
)
throws
Exception
{
String
key
=
onlineKey
+
EncryptUtils
.
desDecrypt
(
val
);
redisTemplate
.
delete
(
key
);
}
public
void
logout
(
String
token
)
{
String
key
=
onlineKey
+
token
;
redisTemplate
.
delete
(
key
);
}
public
void
download
(
List
<
OnlineUser
>
all
,
HttpServletResponse
response
)
throws
IOException
{
List
<
Map
<
String
,
Object
>>
list
=
new
ArrayList
<>();
for
(
OnlineUser
user
:
all
)
{
Map
<
String
,
Object
>
map
=
new
LinkedHashMap
<>();
map
.
put
(
"用户名"
,
user
.
getUserName
());
map
.
put
(
"岗位"
,
user
.
getJob
());
map
.
put
(
"登录IP"
,
user
.
getIp
());
map
.
put
(
"登录地点"
,
user
.
getAddress
());
map
.
put
(
"浏览器"
,
user
.
getBrowser
());
map
.
put
(
"登录日期"
,
user
.
getLoginTime
());
list
.
add
(
map
);
}
FileUtil
.
downloadExcel
(
list
,
response
);
}
}
eladmin-system/src/main/java/me/zhengjie/modules/security/utils/JwtTokenUtil.java
View file @
fd9fb2a6
...
@@ -6,6 +6,8 @@ import me.zhengjie.modules.security.security.JwtUser;
...
@@ -6,6 +6,8 @@ import me.zhengjie.modules.security.security.JwtUser;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.security.core.userdetails.UserDetails
;
import
org.springframework.security.core.userdetails.UserDetails
;
import
org.springframework.stereotype.Component
;
import
org.springframework.stereotype.Component
;
import
javax.servlet.http.HttpServletRequest
;
import
java.io.Serializable
;
import
java.io.Serializable
;
import
java.util.Date
;
import
java.util.Date
;
import
java.util.HashMap
;
import
java.util.HashMap
;
...
@@ -31,15 +33,15 @@ public class JwtTokenUtil implements Serializable {
...
@@ -31,15 +33,15 @@ public class JwtTokenUtil implements Serializable {
return
getClaimFromToken
(
token
,
Claims:
:
getSubject
);
return
getClaimFromToken
(
token
,
Claims:
:
getSubject
);
}
}
p
ublic
Date
getIssuedAtDateFromToken
(
String
token
)
{
p
rivate
Date
getIssuedAtDateFromToken
(
String
token
)
{
return
getClaimFromToken
(
token
,
Claims:
:
getIssuedAt
);
return
getClaimFromToken
(
token
,
Claims:
:
getIssuedAt
);
}
}
p
ublic
Date
getExpirationDateFromToken
(
String
token
)
{
p
rivate
Date
getExpirationDateFromToken
(
String
token
)
{
return
getClaimFromToken
(
token
,
Claims:
:
getExpiration
);
return
getClaimFromToken
(
token
,
Claims:
:
getExpiration
);
}
}
p
ublic
<
T
>
T
getClaimFromToken
(
String
token
,
Function
<
Claims
,
T
>
claimsResolver
)
{
p
rivate
<
T
>
T
getClaimFromToken
(
String
token
,
Function
<
Claims
,
T
>
claimsResolver
)
{
final
Claims
claims
=
getAllClaimsFromToken
(
token
);
final
Claims
claims
=
getAllClaimsFromToken
(
token
);
return
claimsResolver
.
apply
(
claims
);
return
claimsResolver
.
apply
(
claims
);
}
}
...
@@ -103,6 +105,14 @@ public class JwtTokenUtil implements Serializable {
...
@@ -103,6 +105,14 @@ public class JwtTokenUtil implements Serializable {
.
compact
();
.
compact
();
}
}
public
String
getToken
(
HttpServletRequest
request
){
final
String
requestHeader
=
request
.
getHeader
(
tokenHeader
);
if
(
requestHeader
!=
null
&&
requestHeader
.
startsWith
(
"Bearer "
))
{
return
requestHeader
.
substring
(
7
);
}
return
null
;
}
public
Boolean
validateToken
(
String
token
,
UserDetails
userDetails
)
{
public
Boolean
validateToken
(
String
token
,
UserDetails
userDetails
)
{
JwtUser
user
=
(
JwtUser
)
userDetails
;
JwtUser
user
=
(
JwtUser
)
userDetails
;
final
Date
created
=
getIssuedAtDateFromToken
(
token
);
final
Date
created
=
getIssuedAtDateFromToken
(
token
);
...
...
Prev
1
2
3
4
5
6
7
8
9
…
12
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