Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
W
wangxiaolu-sfa-common-security
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
sfa
wangxiaolu-sfa-common-security
Commits
5fcd1390
提交
5fcd1390
authored
10月 09, 2024
作者:
李秋林
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
初始化代码
上级
隐藏空白字符变更
内嵌
并排
正在显示
22 个修改的文件
包含
1621 行增加
和
0 行删除
+1621
-0
pom.xml
pom.xml
+42
-0
EnableCustomConfig.java
...om/sfa/common/security/annotation/EnableCustomConfig.java
+31
-0
EnableRyFeignClients.java
.../sfa/common/security/annotation/EnableRyFeignClients.java
+27
-0
InnerAuth.java
...in/java/com/sfa/common/security/annotation/InnerAuth.java
+20
-0
Logical.java
...main/java/com/sfa/common/security/annotation/Logical.java
+20
-0
RequiresLogin.java
...ava/com/sfa/common/security/annotation/RequiresLogin.java
+18
-0
RequiresPermissions.java
...m/sfa/common/security/annotation/RequiresPermissions.java
+27
-0
RequiresRoles.java
...ava/com/sfa/common/security/annotation/RequiresRoles.java
+26
-0
InnerAuthAspect.java
.../java/com/sfa/common/security/aspect/InnerAuthAspect.java
+51
-0
PreAuthorizeAspect.java
...va/com/sfa/common/security/aspect/PreAuthorizeAspect.java
+97
-0
AuthLogic.java
src/main/java/com/sfa/common/security/auth/AuthLogic.java
+373
-0
AuthUtil.java
src/main/java/com/sfa/common/security/auth/AuthUtil.java
+167
-0
ApplicationConfig.java
...ava/com/sfa/common/security/config/ApplicationConfig.java
+22
-0
WebMvcConfig.java
...ain/java/com/sfa/common/security/config/WebMvcConfig.java
+33
-0
FeignAutoConfiguration.java
...com/sfa/common/security/feign/FeignAutoConfiguration.java
+20
-0
FeignRequestInterceptor.java
...om/sfa/common/security/feign/FeignRequestInterceptor.java
+55
-0
GlobalExceptionHandler.java
...m/sfa/common/security/handler/GlobalExceptionHandler.java
+166
-0
HeaderInterceptor.java
...om/sfa/common/security/interceptor/HeaderInterceptor.java
+54
-0
TokenService.java
...in/java/com/sfa/common/security/service/TokenService.java
+175
-0
DictUtils.java
src/main/java/com/sfa/common/security/utils/DictUtils.java
+75
-0
SecurityUtils.java
...ain/java/com/sfa/common/security/utils/SecurityUtils.java
+117
-0
org.springframework.boot.autoconfigure.AutoConfiguration.imports
...ingframework.boot.autoconfigure.AutoConfiguration.imports
+5
-0
没有找到文件。
pom.xml
0 → 100644
浏览文件 @
5fcd1390
<?xml version="1.0" encoding="UTF-8"?>
<project
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns=
"http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation=
"http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"
>
<parent>
<groupId>
com.wangxiaolu.sfa
</groupId>
<artifactId>
wangxiaolu-sfa-parent
</artifactId>
<version>
0.0.1
</version>
<relativePath/>
</parent>
<modelVersion>
4.0.0
</modelVersion>
<name>
wangxiaolu-sfa-common-security
</name>
<artifactId>
wangxiaolu-sfa-common-security
</artifactId>
<version>
0.0.1
</version>
<description>
wangxiaolu-sfa-common-security安全模块
</description>
<dependencies>
<!-- Spring Web -->
<dependency>
<groupId>
org.springframework
</groupId>
<artifactId>
spring-webmvc
</artifactId>
</dependency>
<!-- RuoYi Api System -->
<dependency>
<groupId>
com.wangxiaolu.sfa
</groupId>
<artifactId>
wangxiaolu-sfa-api-system
</artifactId>
</dependency>
<!-- RuoYi Common Redis-->
<dependency>
<groupId>
com.wangxiaolu.sfa
</groupId>
<artifactId>
wangxiaolu-sfa-common-redis
</artifactId>
</dependency>
</dependencies>
</project>
src/main/java/com/sfa/common/security/annotation/EnableCustomConfig.java
0 → 100644
浏览文件 @
5fcd1390
package
com
.
sfa
.
common
.
security
.
annotation
;
import
java.lang.annotation.Documented
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Inherited
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
import
org.mybatis.spring.annotation.MapperScan
;
import
org.springframework.context.annotation.EnableAspectJAutoProxy
;
import
org.springframework.context.annotation.Import
;
import
org.springframework.scheduling.annotation.EnableAsync
;
import
com.sfa.common.security.config.ApplicationConfig
;
import
com.sfa.common.security.feign.FeignAutoConfiguration
;
@Target
(
ElementType
.
TYPE
)
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Documented
@Inherited
// 表示通过aop框架暴露该代理对象,AopContext能够访问
@EnableAspectJAutoProxy
(
exposeProxy
=
true
)
// 指定要扫描的Mapper类的包的路径
@MapperScan
(
"com.sfa.**.mapper"
)
// 开启线程异步执行
@EnableAsync
// 自动加载类
@Import
({
ApplicationConfig
.
class
,
FeignAutoConfiguration
.
class
})
public
@interface
EnableCustomConfig
{
}
src/main/java/com/sfa/common/security/annotation/EnableRyFeignClients.java
0 → 100644
浏览文件 @
5fcd1390
package
com
.
sfa
.
common
.
security
.
annotation
;
import
org.springframework.cloud.openfeign.EnableFeignClients
;
import
java.lang.annotation.*
;
/**
* 自定义feign注解
* 添加basePackages路径
*
* @author ruoyi
*/
@Target
(
ElementType
.
TYPE
)
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Documented
@EnableFeignClients
public
@interface
EnableRyFeignClients
{
String
[]
value
()
default
{};
String
[]
basePackages
()
default
{
"com.sfa"
};
Class
<?>[]
basePackageClasses
()
default
{};
Class
<?>[]
defaultConfiguration
()
default
{};
Class
<?>[]
clients
()
default
{};
}
src/main/java/com/sfa/common/security/annotation/InnerAuth.java
0 → 100644
浏览文件 @
5fcd1390
package
com
.
sfa
.
common
.
security
.
annotation
;
import
java.lang.annotation.*
;
/**
* 内部认证注解
*
* @author ruoyi
*/
@Target
(
ElementType
.
METHOD
)
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Documented
public
@interface
InnerAuth
{
/**
* 是否校验用户信息
*/
boolean
isUser
()
default
false
;
}
\ No newline at end of file
src/main/java/com/sfa/common/security/annotation/Logical.java
0 → 100644
浏览文件 @
5fcd1390
package
com
.
sfa
.
common
.
security
.
annotation
;
/**
* 权限注解的验证模式
*
* @author ruoyi
*
*/
public
enum
Logical
{
/**
* 必须具有所有的元素
*/
AND
,
/**
* 只需具有其中一个元素
*/
OR
}
src/main/java/com/sfa/common/security/annotation/RequiresLogin.java
0 → 100644
浏览文件 @
5fcd1390
package
com
.
sfa
.
common
.
security
.
annotation
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
/**
* 登录认证:只有登录之后才能进入该方法
*
* @author ruoyi
*
*/
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Target
({
ElementType
.
METHOD
,
ElementType
.
TYPE
})
public
@interface
RequiresLogin
{
}
src/main/java/com/sfa/common/security/annotation/RequiresPermissions.java
0 → 100644
浏览文件 @
5fcd1390
package
com
.
sfa
.
common
.
security
.
annotation
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
/**
* 权限认证:必须具有指定权限才能进入该方法
*
* @author ruoyi
*
*/
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Target
({
ElementType
.
METHOD
,
ElementType
.
TYPE
})
public
@interface
RequiresPermissions
{
/**
* 需要校验的权限码
*/
String
[]
value
()
default
{};
/**
* 验证模式:AND | OR,默认AND
*/
Logical
logical
()
default
Logical
.
AND
;
}
src/main/java/com/sfa/common/security/annotation/RequiresRoles.java
0 → 100644
浏览文件 @
5fcd1390
package
com
.
sfa
.
common
.
security
.
annotation
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
/**
* 角色认证:必须具有指定角色标识才能进入该方法
*
* @author ruoyi
*/
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Target
({
ElementType
.
METHOD
,
ElementType
.
TYPE
})
public
@interface
RequiresRoles
{
/**
* 需要校验的角色标识
*/
String
[]
value
()
default
{};
/**
* 验证逻辑:AND | OR,默认AND
*/
Logical
logical
()
default
Logical
.
AND
;
}
src/main/java/com/sfa/common/security/aspect/InnerAuthAspect.java
0 → 100644
浏览文件 @
5fcd1390
package
com
.
sfa
.
common
.
security
.
aspect
;
import
org.aspectj.lang.ProceedingJoinPoint
;
import
org.aspectj.lang.annotation.Around
;
import
org.aspectj.lang.annotation.Aspect
;
import
org.springframework.core.Ordered
;
import
org.springframework.stereotype.Component
;
import
com.sfa.common.core.constant.SecurityConstants
;
import
com.sfa.common.core.exception.InnerAuthException
;
import
com.sfa.common.core.utils.ServletUtils
;
import
com.sfa.common.core.utils.StringUtils
;
import
com.sfa.common.security.annotation.InnerAuth
;
/**
* 内部服务调用验证处理
*
* @author ruoyi
*/
@Aspect
@Component
public
class
InnerAuthAspect
implements
Ordered
{
@Around
(
"@annotation(innerAuth)"
)
public
Object
innerAround
(
ProceedingJoinPoint
point
,
InnerAuth
innerAuth
)
throws
Throwable
{
String
source
=
ServletUtils
.
getRequest
().
getHeader
(
SecurityConstants
.
FROM_SOURCE
);
// 内部请求验证
if
(!
StringUtils
.
equals
(
SecurityConstants
.
INNER
,
source
))
{
throw
new
InnerAuthException
(
"没有内部访问权限,不允许访问"
);
}
String
userid
=
ServletUtils
.
getRequest
().
getHeader
(
SecurityConstants
.
DETAILS_USER_ID
);
String
username
=
ServletUtils
.
getRequest
().
getHeader
(
SecurityConstants
.
DETAILS_USERNAME
);
// 用户信息验证
if
(
innerAuth
.
isUser
()
&&
(
StringUtils
.
isEmpty
(
userid
)
||
StringUtils
.
isEmpty
(
username
)))
{
throw
new
InnerAuthException
(
"没有设置用户信息,不允许访问 "
);
}
return
point
.
proceed
();
}
/**
* 确保在权限认证aop执行前执行
*/
@Override
public
int
getOrder
()
{
return
Ordered
.
HIGHEST_PRECEDENCE
+
1
;
}
}
src/main/java/com/sfa/common/security/aspect/PreAuthorizeAspect.java
0 → 100644
浏览文件 @
5fcd1390
package
com
.
sfa
.
common
.
security
.
aspect
;
import
java.lang.reflect.Method
;
import
org.aspectj.lang.ProceedingJoinPoint
;
import
org.aspectj.lang.annotation.Around
;
import
org.aspectj.lang.annotation.Aspect
;
import
org.aspectj.lang.annotation.Pointcut
;
import
org.aspectj.lang.reflect.MethodSignature
;
import
org.springframework.stereotype.Component
;
import
com.sfa.common.security.annotation.RequiresLogin
;
import
com.sfa.common.security.annotation.RequiresPermissions
;
import
com.sfa.common.security.annotation.RequiresRoles
;
import
com.sfa.common.security.auth.AuthUtil
;
/**
* 基于 Spring Aop 的注解鉴权
*
* @author kong
*/
@Aspect
@Component
public
class
PreAuthorizeAspect
{
/**
* 构建
*/
public
PreAuthorizeAspect
()
{
}
/**
* 定义AOP签名 (切入所有使用鉴权注解的方法)
*/
public
static
final
String
POINTCUT_SIGN
=
" @annotation(com.sfa.common.security.annotation.RequiresLogin) || "
+
"@annotation(com.sfa.common.security.annotation.RequiresPermissions) || "
+
"@annotation(com.sfa.common.security.annotation.RequiresRoles)"
;
/**
* 声明AOP签名
*/
@Pointcut
(
POINTCUT_SIGN
)
public
void
pointcut
()
{
}
/**
* 环绕切入
*
* @param joinPoint 切面对象
* @return 底层方法执行后的返回值
* @throws Throwable 底层方法抛出的异常
*/
@Around
(
"pointcut()"
)
public
Object
around
(
ProceedingJoinPoint
joinPoint
)
throws
Throwable
{
// 注解鉴权
MethodSignature
signature
=
(
MethodSignature
)
joinPoint
.
getSignature
();
checkMethodAnnotation
(
signature
.
getMethod
());
try
{
// 执行原有逻辑
Object
obj
=
joinPoint
.
proceed
();
return
obj
;
}
catch
(
Throwable
e
)
{
throw
e
;
}
}
/**
* 对一个Method对象进行注解检查
*/
public
void
checkMethodAnnotation
(
Method
method
)
{
// 校验 @RequiresLogin 注解
RequiresLogin
requiresLogin
=
method
.
getAnnotation
(
RequiresLogin
.
class
);
if
(
requiresLogin
!=
null
)
{
AuthUtil
.
checkLogin
();
}
// 校验 @RequiresRoles 注解
RequiresRoles
requiresRoles
=
method
.
getAnnotation
(
RequiresRoles
.
class
);
if
(
requiresRoles
!=
null
)
{
AuthUtil
.
checkRole
(
requiresRoles
);
}
// 校验 @RequiresPermissions 注解
RequiresPermissions
requiresPermissions
=
method
.
getAnnotation
(
RequiresPermissions
.
class
);
if
(
requiresPermissions
!=
null
)
{
AuthUtil
.
checkPermi
(
requiresPermissions
);
}
}
}
src/main/java/com/sfa/common/security/auth/AuthLogic.java
0 → 100644
浏览文件 @
5fcd1390
package
com
.
sfa
.
common
.
security
.
auth
;
import
java.util.Collection
;
import
java.util.HashSet
;
import
java.util.Set
;
import
org.springframework.util.PatternMatchUtils
;
import
com.sfa.common.core.context.SecurityContextHolder
;
import
com.sfa.common.core.exception.auth.NotLoginException
;
import
com.sfa.common.core.exception.auth.NotPermissionException
;
import
com.sfa.common.core.exception.auth.NotRoleException
;
import
com.sfa.common.core.utils.SpringUtils
;
import
com.sfa.common.core.utils.StringUtils
;
import
com.sfa.common.security.annotation.Logical
;
import
com.sfa.common.security.annotation.RequiresLogin
;
import
com.sfa.common.security.annotation.RequiresPermissions
;
import
com.sfa.common.security.annotation.RequiresRoles
;
import
com.sfa.common.security.service.TokenService
;
import
com.sfa.common.security.utils.SecurityUtils
;
import
com.sfa.system.api.model.LoginUser
;
/**
* Token 权限验证,逻辑实现类
*
* @author ruoyi
*/
public
class
AuthLogic
{
/** 所有权限标识 */
private
static
final
String
ALL_PERMISSION
=
"*:*:*"
;
/** 管理员角色权限标识 */
private
static
final
String
SUPER_ADMIN
=
"admin"
;
public
TokenService
tokenService
=
SpringUtils
.
getBean
(
TokenService
.
class
);
/**
* 会话注销
*/
public
void
logout
()
{
String
token
=
SecurityUtils
.
getToken
();
if
(
token
==
null
)
{
return
;
}
logoutByToken
(
token
);
}
/**
* 会话注销,根据指定Token
*/
public
void
logoutByToken
(
String
token
)
{
tokenService
.
delLoginUser
(
token
);
}
/**
* 检验用户是否已经登录,如未登录,则抛出异常
*/
public
void
checkLogin
()
{
getLoginUser
();
}
/**
* 获取当前用户缓存信息, 如果未登录,则抛出异常
*
* @return 用户缓存信息
*/
public
LoginUser
getLoginUser
()
{
String
token
=
SecurityUtils
.
getToken
();
if
(
token
==
null
)
{
throw
new
NotLoginException
(
"未提供token"
);
}
LoginUser
loginUser
=
SecurityUtils
.
getLoginUser
();
if
(
loginUser
==
null
)
{
throw
new
NotLoginException
(
"无效的token"
);
}
return
loginUser
;
}
/**
* 获取当前用户缓存信息, 如果未登录,则抛出异常
*
* @param token 前端传递的认证信息
* @return 用户缓存信息
*/
public
LoginUser
getLoginUser
(
String
token
)
{
return
tokenService
.
getLoginUser
(
token
);
}
/**
* 验证当前用户有效期, 如果相差不足120分钟,自动刷新缓存
*
* @param loginUser 当前用户信息
*/
public
void
verifyLoginUserExpire
(
LoginUser
loginUser
)
{
tokenService
.
verifyToken
(
loginUser
);
}
/**
* 验证用户是否具备某权限
*
* @param permission 权限字符串
* @return 用户是否具备某权限
*/
public
boolean
hasPermi
(
String
permission
)
{
return
hasPermi
(
getPermiList
(),
permission
);
}
/**
* 验证用户是否具备某权限, 如果验证未通过,则抛出异常: NotPermissionException
*
* @param permission 权限字符串
* @return 用户是否具备某权限
*/
public
void
checkPermi
(
String
permission
)
{
if
(!
hasPermi
(
getPermiList
(),
permission
))
{
throw
new
NotPermissionException
(
permission
);
}
}
/**
* 根据注解(@RequiresPermissions)鉴权, 如果验证未通过,则抛出异常: NotPermissionException
*
* @param requiresPermissions 注解对象
*/
public
void
checkPermi
(
RequiresPermissions
requiresPermissions
)
{
SecurityContextHolder
.
setPermission
(
StringUtils
.
join
(
requiresPermissions
.
value
(),
","
));
if
(
requiresPermissions
.
logical
()
==
Logical
.
AND
)
{
checkPermiAnd
(
requiresPermissions
.
value
());
}
else
{
checkPermiOr
(
requiresPermissions
.
value
());
}
}
/**
* 验证用户是否含有指定权限,必须全部拥有
*
* @param permissions 权限列表
*/
public
void
checkPermiAnd
(
String
...
permissions
)
{
Set
<
String
>
permissionList
=
getPermiList
();
for
(
String
permission
:
permissions
)
{
if
(!
hasPermi
(
permissionList
,
permission
))
{
throw
new
NotPermissionException
(
permission
);
}
}
}
/**
* 验证用户是否含有指定权限,只需包含其中一个
*
* @param permissions 权限码数组
*/
public
void
checkPermiOr
(
String
...
permissions
)
{
Set
<
String
>
permissionList
=
getPermiList
();
for
(
String
permission
:
permissions
)
{
if
(
hasPermi
(
permissionList
,
permission
))
{
return
;
}
}
if
(
permissions
.
length
>
0
)
{
throw
new
NotPermissionException
(
permissions
);
}
}
/**
* 判断用户是否拥有某个角色
*
* @param role 角色标识
* @return 用户是否具备某角色
*/
public
boolean
hasRole
(
String
role
)
{
return
hasRole
(
getRoleList
(),
role
);
}
/**
* 判断用户是否拥有某个角色, 如果验证未通过,则抛出异常: NotRoleException
*
* @param role 角色标识
*/
public
void
checkRole
(
String
role
)
{
if
(!
hasRole
(
role
))
{
throw
new
NotRoleException
(
role
);
}
}
/**
* 根据注解(@RequiresRoles)鉴权
*
* @param requiresRoles 注解对象
*/
public
void
checkRole
(
RequiresRoles
requiresRoles
)
{
if
(
requiresRoles
.
logical
()
==
Logical
.
AND
)
{
checkRoleAnd
(
requiresRoles
.
value
());
}
else
{
checkRoleOr
(
requiresRoles
.
value
());
}
}
/**
* 验证用户是否含有指定角色,必须全部拥有
*
* @param roles 角色标识数组
*/
public
void
checkRoleAnd
(
String
...
roles
)
{
Set
<
String
>
roleList
=
getRoleList
();
for
(
String
role
:
roles
)
{
if
(!
hasRole
(
roleList
,
role
))
{
throw
new
NotRoleException
(
role
);
}
}
}
/**
* 验证用户是否含有指定角色,只需包含其中一个
*
* @param roles 角色标识数组
*/
public
void
checkRoleOr
(
String
...
roles
)
{
Set
<
String
>
roleList
=
getRoleList
();
for
(
String
role
:
roles
)
{
if
(
hasRole
(
roleList
,
role
))
{
return
;
}
}
if
(
roles
.
length
>
0
)
{
throw
new
NotRoleException
(
roles
);
}
}
/**
* 根据注解(@RequiresLogin)鉴权
*
* @param at 注解对象
*/
public
void
checkByAnnotation
(
RequiresLogin
at
)
{
this
.
checkLogin
();
}
/**
* 根据注解(@RequiresRoles)鉴权
*
* @param at 注解对象
*/
public
void
checkByAnnotation
(
RequiresRoles
at
)
{
String
[]
roleArray
=
at
.
value
();
if
(
at
.
logical
()
==
Logical
.
AND
)
{
this
.
checkRoleAnd
(
roleArray
);
}
else
{
this
.
checkRoleOr
(
roleArray
);
}
}
/**
* 根据注解(@RequiresPermissions)鉴权
*
* @param at 注解对象
*/
public
void
checkByAnnotation
(
RequiresPermissions
at
)
{
String
[]
permissionArray
=
at
.
value
();
if
(
at
.
logical
()
==
Logical
.
AND
)
{
this
.
checkPermiAnd
(
permissionArray
);
}
else
{
this
.
checkPermiOr
(
permissionArray
);
}
}
/**
* 获取当前账号的角色列表
*
* @return 角色列表
*/
public
Set
<
String
>
getRoleList
()
{
try
{
LoginUser
loginUser
=
getLoginUser
();
return
loginUser
.
getRoles
();
}
catch
(
Exception
e
)
{
return
new
HashSet
<>();
}
}
/**
* 获取当前账号的权限列表
*
* @return 权限列表
*/
public
Set
<
String
>
getPermiList
()
{
try
{
LoginUser
loginUser
=
getLoginUser
();
return
loginUser
.
getPermissions
();
}
catch
(
Exception
e
)
{
return
new
HashSet
<>();
}
}
/**
* 判断是否包含权限
*
* @param authorities 权限列表
* @param permission 权限字符串
* @return 用户是否具备某权限
*/
public
boolean
hasPermi
(
Collection
<
String
>
authorities
,
String
permission
)
{
return
authorities
.
stream
().
filter
(
StringUtils:
:
hasText
)
.
anyMatch
(
x
->
ALL_PERMISSION
.
equals
(
x
)
||
PatternMatchUtils
.
simpleMatch
(
x
,
permission
));
}
/**
* 判断是否包含角色
*
* @param roles 角色列表
* @param role 角色
* @return 用户是否具备某角色权限
*/
public
boolean
hasRole
(
Collection
<
String
>
roles
,
String
role
)
{
return
roles
.
stream
().
filter
(
StringUtils:
:
hasText
)
.
anyMatch
(
x
->
SUPER_ADMIN
.
equals
(
x
)
||
PatternMatchUtils
.
simpleMatch
(
x
,
role
));
}
}
src/main/java/com/sfa/common/security/auth/AuthUtil.java
0 → 100644
浏览文件 @
5fcd1390
package
com
.
sfa
.
common
.
security
.
auth
;
import
com.sfa.common.security.annotation.RequiresPermissions
;
import
com.sfa.common.security.annotation.RequiresRoles
;
import
com.sfa.system.api.model.LoginUser
;
/**
* Token 权限验证工具类
*
* @author ruoyi
*/
public
class
AuthUtil
{
/**
* 底层的 AuthLogic 对象
*/
public
static
AuthLogic
authLogic
=
new
AuthLogic
();
/**
* 会话注销
*/
public
static
void
logout
()
{
authLogic
.
logout
();
}
/**
* 会话注销,根据指定Token
*
* @param token 指定token
*/
public
static
void
logoutByToken
(
String
token
)
{
authLogic
.
logoutByToken
(
token
);
}
/**
* 检验当前会话是否已经登录,如未登录,则抛出异常
*/
public
static
void
checkLogin
()
{
authLogic
.
checkLogin
();
}
/**
* 获取当前登录用户信息
*
* @param token 指定token
* @return 用户信息
*/
public
static
LoginUser
getLoginUser
(
String
token
)
{
return
authLogic
.
getLoginUser
(
token
);
}
/**
* 验证当前用户有效期
*
* @param loginUser 用户信息
*/
public
static
void
verifyLoginUserExpire
(
LoginUser
loginUser
)
{
authLogic
.
verifyLoginUserExpire
(
loginUser
);
}
/**
* 当前账号是否含有指定角色标识, 返回true或false
*
* @param role 角色标识
* @return 是否含有指定角色标识
*/
public
static
boolean
hasRole
(
String
role
)
{
return
authLogic
.
hasRole
(
role
);
}
/**
* 当前账号是否含有指定角色标识, 如果验证未通过,则抛出异常: NotRoleException
*
* @param role 角色标识
*/
public
static
void
checkRole
(
String
role
)
{
authLogic
.
checkRole
(
role
);
}
/**
* 根据注解传入参数鉴权, 如果验证未通过,则抛出异常: NotRoleException
*
* @param requiresRoles 角色权限注解
*/
public
static
void
checkRole
(
RequiresRoles
requiresRoles
)
{
authLogic
.
checkRole
(
requiresRoles
);
}
/**
* 当前账号是否含有指定角色标识 [指定多个,必须全部验证通过]
*
* @param roles 角色标识数组
*/
public
static
void
checkRoleAnd
(
String
...
roles
)
{
authLogic
.
checkRoleAnd
(
roles
);
}
/**
* 当前账号是否含有指定角色标识 [指定多个,只要其一验证通过即可]
*
* @param roles 角色标识数组
*/
public
static
void
checkRoleOr
(
String
...
roles
)
{
authLogic
.
checkRoleOr
(
roles
);
}
/**
* 当前账号是否含有指定权限, 返回true或false
*
* @param permission 权限码
* @return 是否含有指定权限
*/
public
static
boolean
hasPermi
(
String
permission
)
{
return
authLogic
.
hasPermi
(
permission
);
}
/**
* 当前账号是否含有指定权限, 如果验证未通过,则抛出异常: NotPermissionException
*
* @param permission 权限码
*/
public
static
void
checkPermi
(
String
permission
)
{
authLogic
.
checkPermi
(
permission
);
}
/**
* 根据注解传入参数鉴权, 如果验证未通过,则抛出异常: NotPermissionException
*
* @param requiresPermissions 权限注解
*/
public
static
void
checkPermi
(
RequiresPermissions
requiresPermissions
)
{
authLogic
.
checkPermi
(
requiresPermissions
);
}
/**
* 当前账号是否含有指定权限 [指定多个,必须全部验证通过]
*
* @param permissions 权限码数组
*/
public
static
void
checkPermiAnd
(
String
...
permissions
)
{
authLogic
.
checkPermiAnd
(
permissions
);
}
/**
* 当前账号是否含有指定权限 [指定多个,只要其一验证通过即可]
*
* @param permissions 权限码数组
*/
public
static
void
checkPermiOr
(
String
...
permissions
)
{
authLogic
.
checkPermiOr
(
permissions
);
}
}
src/main/java/com/sfa/common/security/config/ApplicationConfig.java
0 → 100644
浏览文件 @
5fcd1390
package
com
.
sfa
.
common
.
security
.
config
;
import
java.util.TimeZone
;
import
org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer
;
import
org.springframework.context.annotation.Bean
;
/**
* 系统配置
*
* @author ruoyi
*/
public
class
ApplicationConfig
{
/**
* 时区配置
*/
@Bean
public
Jackson2ObjectMapperBuilderCustomizer
jacksonObjectMapperCustomization
()
{
return
jacksonObjectMapperBuilder
->
jacksonObjectMapperBuilder
.
timeZone
(
TimeZone
.
getDefault
());
}
}
src/main/java/com/sfa/common/security/config/WebMvcConfig.java
0 → 100644
浏览文件 @
5fcd1390
package
com
.
sfa
.
common
.
security
.
config
;
import
org.springframework.web.servlet.config.annotation.InterceptorRegistry
;
import
org.springframework.web.servlet.config.annotation.WebMvcConfigurer
;
import
com.sfa.common.security.interceptor.HeaderInterceptor
;
/**
* 拦截器配置
*
* @author ruoyi
*/
public
class
WebMvcConfig
implements
WebMvcConfigurer
{
/** 不需要拦截地址 */
public
static
final
String
[]
excludeUrls
=
{
"/auto/login"
,
"/auto/logout"
,
"/auto/refresh"
};
@Override
public
void
addInterceptors
(
InterceptorRegistry
registry
)
{
registry
.
addInterceptor
(
getHeaderInterceptor
())
.
addPathPatterns
(
"/**"
)
.
excludePathPatterns
(
excludeUrls
)
.
order
(-
10
);
}
/**
* 自定义请求头拦截器
*/
public
HeaderInterceptor
getHeaderInterceptor
()
{
return
new
HeaderInterceptor
();
}
}
src/main/java/com/sfa/common/security/feign/FeignAutoConfiguration.java
0 → 100644
浏览文件 @
5fcd1390
package
com
.
sfa
.
common
.
security
.
feign
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
feign.RequestInterceptor
;
/**
* Feign 配置注册
*
* @author ruoyi
**/
@Configuration
public
class
FeignAutoConfiguration
{
@Bean
public
RequestInterceptor
requestInterceptor
()
{
return
new
FeignRequestInterceptor
();
}
}
src/main/java/com/sfa/common/security/feign/FeignRequestInterceptor.java
0 → 100644
浏览文件 @
5fcd1390
package
com
.
sfa
.
common
.
security
.
feign
;
import
java.util.Map
;
import
javax.servlet.http.HttpServletRequest
;
import
org.springframework.stereotype.Component
;
import
com.sfa.common.core.constant.SecurityConstants
;
import
com.sfa.common.core.utils.ServletUtils
;
import
com.sfa.common.core.utils.StringUtils
;
import
com.sfa.common.core.utils.ip.IpUtils
;
import
feign.RequestInterceptor
;
import
feign.RequestTemplate
;
/**
* feign 请求拦截器
*
* @author ruoyi
*/
@Component
public
class
FeignRequestInterceptor
implements
RequestInterceptor
{
@Override
public
void
apply
(
RequestTemplate
requestTemplate
)
{
HttpServletRequest
httpServletRequest
=
ServletUtils
.
getRequest
();
if
(
StringUtils
.
isNotNull
(
httpServletRequest
))
{
Map
<
String
,
String
>
headers
=
ServletUtils
.
getHeaders
(
httpServletRequest
);
// 传递用户信息请求头,防止丢失
String
userId
=
headers
.
get
(
SecurityConstants
.
DETAILS_USER_ID
);
if
(
StringUtils
.
isNotEmpty
(
userId
))
{
requestTemplate
.
header
(
SecurityConstants
.
DETAILS_USER_ID
,
userId
);
}
String
userKey
=
headers
.
get
(
SecurityConstants
.
USER_KEY
);
if
(
StringUtils
.
isNotEmpty
(
userKey
))
{
requestTemplate
.
header
(
SecurityConstants
.
USER_KEY
,
userKey
);
}
String
userName
=
headers
.
get
(
SecurityConstants
.
DETAILS_USERNAME
);
if
(
StringUtils
.
isNotEmpty
(
userName
))
{
requestTemplate
.
header
(
SecurityConstants
.
DETAILS_USERNAME
,
userName
);
}
String
authentication
=
headers
.
get
(
SecurityConstants
.
AUTHORIZATION_HEADER
);
if
(
StringUtils
.
isNotEmpty
(
authentication
))
{
requestTemplate
.
header
(
SecurityConstants
.
AUTHORIZATION_HEADER
,
authentication
);
}
// 配置客户端IP
requestTemplate
.
header
(
"X-Forwarded-For"
,
IpUtils
.
getIpAddr
());
}
}
}
\ No newline at end of file
src/main/java/com/sfa/common/security/handler/GlobalExceptionHandler.java
0 → 100644
浏览文件 @
5fcd1390
package
com
.
sfa
.
common
.
security
.
handler
;
import
javax.servlet.http.HttpServletRequest
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.validation.BindException
;
import
org.springframework.web.HttpRequestMethodNotSupportedException
;
import
org.springframework.web.bind.MethodArgumentNotValidException
;
import
org.springframework.web.bind.MissingPathVariableException
;
import
org.springframework.web.bind.annotation.ExceptionHandler
;
import
org.springframework.web.bind.annotation.RestControllerAdvice
;
import
org.springframework.web.method.annotation.MethodArgumentTypeMismatchException
;
import
com.sfa.common.core.constant.HttpStatus
;
import
com.sfa.common.core.exception.DemoModeException
;
import
com.sfa.common.core.exception.InnerAuthException
;
import
com.sfa.common.core.exception.ServiceException
;
import
com.sfa.common.core.exception.auth.NotPermissionException
;
import
com.sfa.common.core.exception.auth.NotRoleException
;
import
com.sfa.common.core.text.Convert
;
import
com.sfa.common.core.utils.StringUtils
;
import
com.sfa.common.core.utils.html.EscapeUtil
;
import
com.sfa.common.core.web.domain.AjaxResult
;
/**
* 全局异常处理器
*
* @author ruoyi
*/
@RestControllerAdvice
public
class
GlobalExceptionHandler
{
private
static
final
Logger
log
=
LoggerFactory
.
getLogger
(
GlobalExceptionHandler
.
class
);
/**
* 权限码异常
*/
@ExceptionHandler
(
NotPermissionException
.
class
)
public
AjaxResult
handleNotPermissionException
(
NotPermissionException
e
,
HttpServletRequest
request
)
{
String
requestURI
=
request
.
getRequestURI
();
log
.
error
(
"请求地址'{}',权限码校验失败'{}'"
,
requestURI
,
e
.
getMessage
());
return
AjaxResult
.
error
(
HttpStatus
.
FORBIDDEN
,
"没有访问权限,请联系管理员授权"
);
}
/**
* 角色权限异常
*/
@ExceptionHandler
(
NotRoleException
.
class
)
public
AjaxResult
handleNotRoleException
(
NotRoleException
e
,
HttpServletRequest
request
)
{
String
requestURI
=
request
.
getRequestURI
();
log
.
error
(
"请求地址'{}',角色权限校验失败'{}'"
,
requestURI
,
e
.
getMessage
());
return
AjaxResult
.
error
(
HttpStatus
.
FORBIDDEN
,
"没有访问权限,请联系管理员授权"
);
}
/**
* 请求方式不支持
*/
@ExceptionHandler
(
HttpRequestMethodNotSupportedException
.
class
)
public
AjaxResult
handleHttpRequestMethodNotSupported
(
HttpRequestMethodNotSupportedException
e
,
HttpServletRequest
request
)
{
String
requestURI
=
request
.
getRequestURI
();
log
.
error
(
"请求地址'{}',不支持'{}'请求"
,
requestURI
,
e
.
getMethod
());
return
AjaxResult
.
error
(
e
.
getMessage
());
}
/**
* 业务异常
*/
@ExceptionHandler
(
ServiceException
.
class
)
public
AjaxResult
handleServiceException
(
ServiceException
e
,
HttpServletRequest
request
)
{
log
.
error
(
e
.
getMessage
(),
e
);
Integer
code
=
e
.
getCode
();
return
StringUtils
.
isNotNull
(
code
)
?
AjaxResult
.
error
(
code
,
e
.
getMessage
())
:
AjaxResult
.
error
(
e
.
getMessage
());
}
/**
* 请求路径中缺少必需的路径变量
*/
@ExceptionHandler
(
MissingPathVariableException
.
class
)
public
AjaxResult
handleMissingPathVariableException
(
MissingPathVariableException
e
,
HttpServletRequest
request
)
{
String
requestURI
=
request
.
getRequestURI
();
log
.
error
(
"请求路径中缺少必需的路径变量'{}',发生系统异常."
,
requestURI
,
e
);
return
AjaxResult
.
error
(
String
.
format
(
"请求路径中缺少必需的路径变量[%s]"
,
e
.
getVariableName
()));
}
/**
* 请求参数类型不匹配
*/
@ExceptionHandler
(
MethodArgumentTypeMismatchException
.
class
)
public
AjaxResult
handleMethodArgumentTypeMismatchException
(
MethodArgumentTypeMismatchException
e
,
HttpServletRequest
request
)
{
String
requestURI
=
request
.
getRequestURI
();
String
value
=
Convert
.
toStr
(
e
.
getValue
());
if
(
StringUtils
.
isNotEmpty
(
value
))
{
value
=
EscapeUtil
.
clean
(
value
);
}
log
.
error
(
"请求参数类型不匹配'{}',发生系统异常."
,
requestURI
,
e
);
return
AjaxResult
.
error
(
String
.
format
(
"请求参数类型不匹配,参数[%s]要求类型为:'%s',但输入值为:'%s'"
,
e
.
getName
(),
e
.
getRequiredType
().
getName
(),
value
));
}
/**
* 拦截未知的运行时异常
*/
@ExceptionHandler
(
RuntimeException
.
class
)
public
AjaxResult
handleRuntimeException
(
RuntimeException
e
,
HttpServletRequest
request
)
{
String
requestURI
=
request
.
getRequestURI
();
log
.
error
(
"请求地址'{}',发生未知异常."
,
requestURI
,
e
);
return
AjaxResult
.
error
(
e
.
getMessage
());
}
/**
* 系统异常
*/
@ExceptionHandler
(
Exception
.
class
)
public
AjaxResult
handleException
(
Exception
e
,
HttpServletRequest
request
)
{
String
requestURI
=
request
.
getRequestURI
();
log
.
error
(
"请求地址'{}',发生系统异常."
,
requestURI
,
e
);
return
AjaxResult
.
error
(
e
.
getMessage
());
}
/**
* 自定义验证异常
*/
@ExceptionHandler
(
BindException
.
class
)
public
AjaxResult
handleBindException
(
BindException
e
)
{
log
.
error
(
e
.
getMessage
(),
e
);
String
message
=
e
.
getAllErrors
().
get
(
0
).
getDefaultMessage
();
return
AjaxResult
.
error
(
message
);
}
/**
* 自定义验证异常
*/
@ExceptionHandler
(
MethodArgumentNotValidException
.
class
)
public
Object
handleMethodArgumentNotValidException
(
MethodArgumentNotValidException
e
)
{
log
.
error
(
e
.
getMessage
(),
e
);
String
message
=
e
.
getBindingResult
().
getFieldError
().
getDefaultMessage
();
return
AjaxResult
.
error
(
message
);
}
/**
* 内部认证异常
*/
@ExceptionHandler
(
InnerAuthException
.
class
)
public
AjaxResult
handleInnerAuthException
(
InnerAuthException
e
)
{
return
AjaxResult
.
error
(
e
.
getMessage
());
}
/**
* 演示模式异常
*/
@ExceptionHandler
(
DemoModeException
.
class
)
public
AjaxResult
handleDemoModeException
(
DemoModeException
e
)
{
return
AjaxResult
.
error
(
"演示模式,不允许操作"
);
}
}
src/main/java/com/sfa/common/security/interceptor/HeaderInterceptor.java
0 → 100644
浏览文件 @
5fcd1390
package
com
.
sfa
.
common
.
security
.
interceptor
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
org.springframework.web.method.HandlerMethod
;
import
org.springframework.web.servlet.AsyncHandlerInterceptor
;
import
com.sfa.common.core.constant.SecurityConstants
;
import
com.sfa.common.core.context.SecurityContextHolder
;
import
com.sfa.common.core.utils.ServletUtils
;
import
com.sfa.common.core.utils.StringUtils
;
import
com.sfa.common.security.auth.AuthUtil
;
import
com.sfa.common.security.utils.SecurityUtils
;
import
com.sfa.system.api.model.LoginUser
;
/**
* 自定义请求头拦截器,将Header数据封装到线程变量中方便获取
* 注意:此拦截器会同时验证当前用户有效期自动刷新有效期
*
* @author ruoyi
*/
public
class
HeaderInterceptor
implements
AsyncHandlerInterceptor
{
@Override
public
boolean
preHandle
(
HttpServletRequest
request
,
HttpServletResponse
response
,
Object
handler
)
throws
Exception
{
if
(!(
handler
instanceof
HandlerMethod
))
{
return
true
;
}
SecurityContextHolder
.
setUserId
(
ServletUtils
.
getHeader
(
request
,
SecurityConstants
.
DETAILS_USER_ID
));
SecurityContextHolder
.
setUserName
(
ServletUtils
.
getHeader
(
request
,
SecurityConstants
.
DETAILS_USERNAME
));
SecurityContextHolder
.
setUserKey
(
ServletUtils
.
getHeader
(
request
,
SecurityConstants
.
USER_KEY
));
String
token
=
SecurityUtils
.
getToken
();
if
(
StringUtils
.
isNotEmpty
(
token
))
{
LoginUser
loginUser
=
AuthUtil
.
getLoginUser
(
token
);
if
(
StringUtils
.
isNotNull
(
loginUser
))
{
AuthUtil
.
verifyLoginUserExpire
(
loginUser
);
SecurityContextHolder
.
set
(
SecurityConstants
.
LOGIN_USER
,
loginUser
);
}
}
return
true
;
}
@Override
public
void
afterCompletion
(
HttpServletRequest
request
,
HttpServletResponse
response
,
Object
handler
,
Exception
ex
)
throws
Exception
{
SecurityContextHolder
.
remove
();
}
}
src/main/java/com/sfa/common/security/service/TokenService.java
0 → 100644
浏览文件 @
5fcd1390
package
com
.
sfa
.
common
.
security
.
service
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.concurrent.TimeUnit
;
import
javax.servlet.http.HttpServletRequest
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Component
;
import
com.sfa.common.core.constant.CacheConstants
;
import
com.sfa.common.core.constant.SecurityConstants
;
import
com.sfa.common.core.utils.JwtUtils
;
import
com.sfa.common.core.utils.ServletUtils
;
import
com.sfa.common.core.utils.StringUtils
;
import
com.sfa.common.core.utils.ip.IpUtils
;
import
com.sfa.common.core.utils.uuid.IdUtils
;
import
com.sfa.common.redis.service.RedisService
;
import
com.sfa.common.security.utils.SecurityUtils
;
import
com.sfa.system.api.model.LoginUser
;
/**
* token验证处理
*
* @author ruoyi
*/
@Component
public
class
TokenService
{
private
static
final
Logger
log
=
LoggerFactory
.
getLogger
(
TokenService
.
class
);
@Autowired
private
RedisService
redisService
;
protected
static
final
long
MILLIS_SECOND
=
1000
;
protected
static
final
long
MILLIS_MINUTE
=
60
*
MILLIS_SECOND
;
private
final
static
long
expireTime
=
CacheConstants
.
EXPIRATION
;
private
final
static
String
ACCESS_TOKEN
=
CacheConstants
.
LOGIN_TOKEN_KEY
;
private
final
static
Long
MILLIS_MINUTE_TEN
=
CacheConstants
.
REFRESH_TIME
*
MILLIS_MINUTE
;
/**
* 创建令牌
*/
public
Map
<
String
,
Object
>
createToken
(
LoginUser
loginUser
)
{
String
token
=
IdUtils
.
fastUUID
();
Long
userId
=
loginUser
.
getSysUser
().
getUserId
();
String
userName
=
loginUser
.
getSysUser
().
getUserName
();
loginUser
.
setToken
(
token
);
loginUser
.
setUserid
(
userId
);
loginUser
.
setUsername
(
userName
);
loginUser
.
setIpaddr
(
IpUtils
.
getIpAddr
());
refreshToken
(
loginUser
);
// Jwt存储信息
Map
<
String
,
Object
>
claimsMap
=
new
HashMap
<
String
,
Object
>();
claimsMap
.
put
(
SecurityConstants
.
USER_KEY
,
token
);
claimsMap
.
put
(
SecurityConstants
.
DETAILS_USER_ID
,
userId
);
claimsMap
.
put
(
SecurityConstants
.
DETAILS_USERNAME
,
userName
);
// 接口返回信息
Map
<
String
,
Object
>
rspMap
=
new
HashMap
<
String
,
Object
>();
rspMap
.
put
(
"access_token"
,
JwtUtils
.
createToken
(
claimsMap
));
rspMap
.
put
(
"expires_in"
,
expireTime
);
return
rspMap
;
}
/**
* 获取用户身份信息
*
* @return 用户信息
*/
public
LoginUser
getLoginUser
()
{
return
getLoginUser
(
ServletUtils
.
getRequest
());
}
/**
* 获取用户身份信息
*
* @return 用户信息
*/
public
LoginUser
getLoginUser
(
HttpServletRequest
request
)
{
// 获取请求携带的令牌
String
token
=
SecurityUtils
.
getToken
(
request
);
return
getLoginUser
(
token
);
}
/**
* 获取用户身份信息
*
* @return 用户信息
*/
public
LoginUser
getLoginUser
(
String
token
)
{
LoginUser
user
=
null
;
try
{
if
(
StringUtils
.
isNotEmpty
(
token
))
{
String
userkey
=
JwtUtils
.
getUserKey
(
token
);
user
=
redisService
.
getCacheObject
(
getTokenKey
(
userkey
));
return
user
;
}
}
catch
(
Exception
e
)
{
log
.
error
(
"获取用户信息异常'{}'"
,
e
.
getMessage
());
}
return
user
;
}
/**
* 设置用户身份信息
*/
public
void
setLoginUser
(
LoginUser
loginUser
)
{
if
(
StringUtils
.
isNotNull
(
loginUser
)
&&
StringUtils
.
isNotEmpty
(
loginUser
.
getToken
()))
{
refreshToken
(
loginUser
);
}
}
/**
* 删除用户缓存信息
*/
public
void
delLoginUser
(
String
token
)
{
if
(
StringUtils
.
isNotEmpty
(
token
))
{
String
userkey
=
JwtUtils
.
getUserKey
(
token
);
redisService
.
deleteObject
(
getTokenKey
(
userkey
));
}
}
/**
* 验证令牌有效期,相差不足120分钟,自动刷新缓存
*
* @param loginUser
*/
public
void
verifyToken
(
LoginUser
loginUser
)
{
long
expireTime
=
loginUser
.
getExpireTime
();
long
currentTime
=
System
.
currentTimeMillis
();
if
(
expireTime
-
currentTime
<=
MILLIS_MINUTE_TEN
)
{
refreshToken
(
loginUser
);
}
}
/**
* 刷新令牌有效期
*
* @param loginUser 登录信息
*/
public
void
refreshToken
(
LoginUser
loginUser
)
{
loginUser
.
setLoginTime
(
System
.
currentTimeMillis
());
loginUser
.
setExpireTime
(
loginUser
.
getLoginTime
()
+
expireTime
*
MILLIS_MINUTE
);
// 根据uuid将loginUser缓存
String
userKey
=
getTokenKey
(
loginUser
.
getToken
());
redisService
.
setCacheObject
(
userKey
,
loginUser
,
expireTime
,
TimeUnit
.
MINUTES
);
}
private
String
getTokenKey
(
String
token
)
{
return
ACCESS_TOKEN
+
token
;
}
}
\ No newline at end of file
src/main/java/com/sfa/common/security/utils/DictUtils.java
0 → 100644
浏览文件 @
5fcd1390
package
com
.
sfa
.
common
.
security
.
utils
;
import
java.util.Collection
;
import
java.util.List
;
import
com.alibaba.fastjson2.JSONArray
;
import
com.sfa.common.core.constant.CacheConstants
;
import
com.sfa.common.core.utils.SpringUtils
;
import
com.sfa.common.core.utils.StringUtils
;
import
com.sfa.common.redis.service.RedisService
;
import
com.sfa.system.api.domain.SysDictData
;
/**
* 字典工具类
*
* @author ruoyi
*/
public
class
DictUtils
{
/**
* 设置字典缓存
*
* @param key 参数键
* @param dictDatas 字典数据列表
*/
public
static
void
setDictCache
(
String
key
,
List
<
SysDictData
>
dictDatas
)
{
SpringUtils
.
getBean
(
RedisService
.
class
).
setCacheObject
(
getCacheKey
(
key
),
dictDatas
);
}
/**
* 获取字典缓存
*
* @param key 参数键
* @return dictDatas 字典数据列表
*/
public
static
List
<
SysDictData
>
getDictCache
(
String
key
)
{
JSONArray
arrayCache
=
SpringUtils
.
getBean
(
RedisService
.
class
).
getCacheObject
(
getCacheKey
(
key
));
if
(
StringUtils
.
isNotNull
(
arrayCache
))
{
return
arrayCache
.
toList
(
SysDictData
.
class
);
}
return
null
;
}
/**
* 删除指定字典缓存
*
* @param key 字典键
*/
public
static
void
removeDictCache
(
String
key
)
{
SpringUtils
.
getBean
(
RedisService
.
class
).
deleteObject
(
getCacheKey
(
key
));
}
/**
* 清空字典缓存
*/
public
static
void
clearDictCache
()
{
Collection
<
String
>
keys
=
SpringUtils
.
getBean
(
RedisService
.
class
).
keys
(
CacheConstants
.
SYS_DICT_KEY
+
"*"
);
SpringUtils
.
getBean
(
RedisService
.
class
).
deleteObject
(
keys
);
}
/**
* 设置cache key
*
* @param configKey 参数键
* @return 缓存键key
*/
public
static
String
getCacheKey
(
String
configKey
)
{
return
CacheConstants
.
SYS_DICT_KEY
+
configKey
;
}
}
src/main/java/com/sfa/common/security/utils/SecurityUtils.java
0 → 100644
浏览文件 @
5fcd1390
package
com
.
sfa
.
common
.
security
.
utils
;
import
javax.servlet.http.HttpServletRequest
;
import
org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
;
import
com.sfa.common.core.constant.SecurityConstants
;
import
com.sfa.common.core.constant.TokenConstants
;
import
com.sfa.common.core.context.SecurityContextHolder
;
import
com.sfa.common.core.utils.ServletUtils
;
import
com.sfa.common.core.utils.StringUtils
;
import
com.sfa.system.api.model.LoginUser
;
/**
* 权限获取工具类
*
* @author ruoyi
*/
public
class
SecurityUtils
{
/**
* 获取用户ID
*/
public
static
Long
getUserId
()
{
return
SecurityContextHolder
.
getUserId
();
}
/**
* 获取用户名称
*/
public
static
String
getUsername
()
{
return
SecurityContextHolder
.
getUserName
();
}
/**
* 获取用户key
*/
public
static
String
getUserKey
()
{
return
SecurityContextHolder
.
getUserKey
();
}
/**
* 获取登录用户信息
*/
public
static
LoginUser
getLoginUser
()
{
return
SecurityContextHolder
.
get
(
SecurityConstants
.
LOGIN_USER
,
LoginUser
.
class
);
}
/**
* 获取请求token
*/
public
static
String
getToken
()
{
return
getToken
(
ServletUtils
.
getRequest
());
}
/**
* 根据request获取请求token
*/
public
static
String
getToken
(
HttpServletRequest
request
)
{
// 从header获取token标识
String
token
=
request
.
getHeader
(
TokenConstants
.
AUTHENTICATION
);
return
replaceTokenPrefix
(
token
);
}
/**
* 裁剪token前缀
*/
public
static
String
replaceTokenPrefix
(
String
token
)
{
// 如果前端设置了令牌前缀,则裁剪掉前缀
if
(
StringUtils
.
isNotEmpty
(
token
)
&&
token
.
startsWith
(
TokenConstants
.
PREFIX
))
{
token
=
token
.
replaceFirst
(
TokenConstants
.
PREFIX
,
""
);
}
return
token
;
}
/**
* 是否为管理员
*
* @param userId 用户ID
* @return 结果
*/
public
static
boolean
isAdmin
(
Long
userId
)
{
return
userId
!=
null
&&
1L
==
userId
;
}
/**
* 生成BCryptPasswordEncoder密码
*
* @param password 密码
* @return 加密字符串
*/
public
static
String
encryptPassword
(
String
password
)
{
BCryptPasswordEncoder
passwordEncoder
=
new
BCryptPasswordEncoder
();
return
passwordEncoder
.
encode
(
password
);
}
/**
* 判断密码是否相同
*
* @param rawPassword 真实密码
* @param encodedPassword 加密后字符
* @return 结果
*/
public
static
boolean
matchesPassword
(
String
rawPassword
,
String
encodedPassword
)
{
BCryptPasswordEncoder
passwordEncoder
=
new
BCryptPasswordEncoder
();
return
passwordEncoder
.
matches
(
rawPassword
,
encodedPassword
);
}
}
src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
0 → 100644
浏览文件 @
5fcd1390
com.sfa.common.security.config.WebMvcConfig
com.sfa.common.security.service.TokenService
com.sfa.common.security.aspect.PreAuthorizeAspect
com.sfa.common.security.aspect.InnerAuthAspect
com.sfa.common.security.handler.GlobalExceptionHandler
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论