一、实现逻辑分析
整体上用注解通过AOP对sql进行修改,从而实现数据筛选
1.Controller调用Service层方法
2.Service层方法上注解@DataScope
3.注解@DataScope 通过切面类DataScopeAspect获取前
端传输的参数,结合通过SpringSecurity获得的用户信息,
将参数[BaseEntity的子类]属性param赋值
4.xml Mapper [通过子类属性params 使用SQL 语句过滤
数据]
二、代码分析
1.Controller层
该接口startpage()为数据分页所需函数
该接口调用Service层中selectUserList函数
@PreAuthorize ( "@ss.hasPermi('system:user:list')" )
@GetMapping ( "/list" )
public TableDataInfo list ( SysUser user)
{
startPage ( ) ;
List < SysUser > list = userService. selectUserList ( user) ;
return getDataTable ( list) ;
}
2.Service层
该方法使用注解@DataScope传参为部门和用户
@Override
@DataScope ( deptAlias = "d" , userAlias = "u" )
public List < SysUser > selectUserList ( SysUser user)
{
return userMapper. selectUserList ( user) ;
}
3.注解
@Target ( ElementType . METHOD)
@Retention ( RetentionPolicy . RUNTIME)
@Documented
public @interface DataScope
{
public String deptAlias ( ) default "" ;
public String userAlias ( ) default "" ;
}
4.注解对应的切面类
监听注解,类型为controllerDataScope 对应的注解类
型@DataScope
@Before ( "@annotation(controllerDataScope)" )
public void doBefore ( JoinPoint point, DataScope controllerDataScope) throws Throwable
{
clearDataScope ( point) ;
handleDataScope ( point, controllerDataScope) ;
}
函数clearDataScope判断传入参数是否为BaseEntity的
子类,从而防止SQL注入
private void clearDataScope ( final JoinPoint joinPoint)
{
Object params = joinPoint. getArgs ( ) [ 0 ] ;
if ( StringUtils . isNotNull ( params) && params instanceof BaseEntity )
{
BaseEntity baseEntity = ( BaseEntity ) params;
baseEntity. getParams ( ) . put ( DATA_SCOPE, "" ) ;
}
}
4.1当角色拥有全部权限
代码调试结果中,datascop为1,即切面类定义
的DATA_SCOPE_ALL
4.1当角色拥有自定义权限
代码调试结果中,datascop为2,即切面类定义
的DATA_SCOPE_CUSTOM
4.1当角色拥有本人权限
代码调试结果中,datascop为5,即切面类定义
的DATA_SCOPE_SELF
5.Mapper层 java代码
public List < SysUser > selectUserList ( SysUser sysUser) ;
5.Mapper层 xml代码
< select id= "selectUserList" parameterType= "SysUser" resultMap= "SysUserResult" >
select u. user_id, u. dept_id, u. nick_name, u. user_name, u. email, u. avatar, u. phonenumber, u. password, u. sex, u. status, u. del_flag, u. login_ip, u. login_date, u. create_by, u. create_time, u. remark, d. dept_name, d. leader from sys_user u
left join sys_dept d on u. dept_id = d. dept_id
where u. del_flag = '0'
< if test= "userId != null and userId != 0" >
AND u. user_id = #{ userId}
< / if >
< if test= "userName != null and userName != ''" >
AND u. user_name like concat ( '%' , #{ userName} , '%' )
< / if >
< if test= "status != null and status != ''" >
AND u. status = #{ status}
< / if >
< if test= "phonenumber != null and phonenumber != ''" >
AND u. phonenumber like concat ( '%' , #{ phonenumber} , '%' )
< / if >
< if test= "params.beginTime != null and params.beginTime != ''" > < ! -- 开始时间检索 -- >
AND date_format ( u. create_time, '%y%m%d' ) & gt; = date_format ( #{ params. beginTime} , '%y%m%d' )
< / if >
< if test= "params.endTime != null and params.endTime != ''" > < ! -- 结束时间检索 -- >
AND date_format ( u. create_time, '%y%m%d' ) & lt; = date_format ( #{ params. endTime} , '%y%m%d' )
< / if >
< if test= "deptId != null and deptId != 0" >
AND ( u. dept_id = #{ deptId} OR u. dept_id IN ( SELECT t. dept_id FROM sys_dept t WHERE find_in_set ( #{ deptId} , ancestors) ) )
< / if >
< ! -- 数据范围过滤 -- >
${ params. dataScope}
< / select>
三、测试结果
1.角色拥有全部权限
代码调试结果中,datascop为1,即切面类定义
的DATA_SCOPE_ALL
没有添加对应SQL
2.角色拥有自定义权限
代码调试结果中,datascop为2,即切面类定义
的DATA_SCOPE_CUSTOM
添加用户所拥有的对应查询SQL
3.角色拥有本人权限
代码调试结果中,datascop为5,即切面类定义
的DATA_SCOPE_SELF
添加用户所拥有的对应查询SQL