程序员的资源宝库

网站首页 > gitee 正文

若依框架学习之数据权限控制 数据权限控制系统默认的有

sanyeah 2024-03-29 17:40:38 gitee 6 ℃ 0 评论

若依框架中的数据权限控制学习记录

若依框架中数据权限控制实现

 

 

 

 

 

  1.  数据权限控制分为所有权限,自定义数据权限,本部门数据权限,本部门及子部门权限,仅自己五个等级的权限控制。
  2. 大致的实现思路:当用户登录之后,通过查询所登录用户的角色和权限信息,角色信息中包含datascope字段控制该用户的数据权限。
  3. 若依自定义了@Datascope注解,作用域为运行时,注解标注在查询用户列表,查询角色列表,以及查询部门列表三个方法上。当执行这三个方法就会对数据权限进行控制。用户登录就会先执行这三个方法。
  4. 若依使用AspectJ对@Datascope注解进行处理,获取注解上的别名@Datascope(deptAlias='d')用于拼接sql。拼接语句中使用的StringUtils.format()方法会将字符串中的{}使用传入的参数一一替代。
  5. 用户登录时,获取到用户的datascope字段后,传入该字段和定义的常量值匹配。匹配到对应值后,将sql语句放进一个Map(String,Object)中,键固定为dataScope,值为sql语句。传入sql语句作为值时,会将sql做一次拼接与截取(
    " AND (" + sqlString.substring(4) + ")"
    )拼接上AND( 并将sql第一个OR截取掉,效果 :and(
    d.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = 101 )
  6. 持久层通过${params.dataScope}取出sql语句拼接执行。
  7. <select id="selectRoleList" parameterType="SysRole" resultMap="SysRoleResult">
    <include refid="selectRoleVo"/>
    where r.del_flag = '0'
    <if test="roleId != null and roleId != 0">
    AND r.role_id = #{roleId}
    </if>
    <if test="roleName != null and roleName != ''">
    AND r.role_name like concat('%', #{roleName}, '%')
    </if>
    <if test="status != null and status != ''">
    AND r.status = #{status}
    </if>
    <if test="roleKey != null and roleKey != ''">
    AND r.role_key like concat('%', #{roleKey}, '%')
    </if>
    <if test="params.beginTime != null and params.beginTime != ''"><!-- 开始时间检索 -->
    and date_format(r.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(r.create_time,'%y%m%d') &lt;= date_format(#{params.endTime},'%y%m%d')
    </if>
    <!-- 数据范围过滤 -->
    ${params.dataScope}
    order by r.role_sort
    </select>
  8. 若依使用的AspectJ代码如下:
  9. package com.ruoyi.framework.aspectj;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.springframework.stereotype.Component;
    import com.ruoyi.common.annotation.DataScope;
    import com.ruoyi.common.core.domain.BaseEntity;
    import com.ruoyi.common.core.domain.entity.SysRole;
    import com.ruoyi.common.core.domain.entity.SysUser;
    import com.ruoyi.common.core.domain.model.LoginUser;
    import com.ruoyi.common.utils.StringUtils;
    import com.ruoyi.common.utils.SecurityUtils;
    
    /**
     * 数据过滤处理
     *
     * @author ruoyi
     */
    @Aspect
    @Component
    public class DataScopeAspect
    {
        /**
         * 全部数据权限
         */
        public static final String DATA_SCOPE_ALL = "1";
    
        /**
         * 自定数据权限
         */
        public static final String DATA_SCOPE_CUSTOM = "2";
    
        /**
         * 部门数据权限
         */
        public static final String DATA_SCOPE_DEPT = "3";
    
        /**
         * 部门及以下数据权限
         */
        public static final String DATA_SCOPE_DEPT_AND_CHILD = "4";
    
        /**
         * 仅本人数据权限
         */
        public static final String DATA_SCOPE_SELF = "5";
    
        /**
         * 数据权限过滤关键字
         */
        public static final String DATA_SCOPE = "dataScope";
    
        @Before("@annotation(controllerDataScope)")
        public void doBefore(JoinPoint point, DataScope controllerDataScope) throws Throwable
        {
            clearDataScope(point);
            handleDataScope(point, controllerDataScope);
        }
    
        protected void handleDataScope(final JoinPoint joinPoint, DataScope controllerDataScope)
        {
            // 获取当前的用户
            LoginUser loginUser = SecurityUtils.getLoginUser();
            if (StringUtils.isNotNull(loginUser))
            {
                SysUser currentUser = loginUser.getUser();
                // 如果是超级管理员,则不过滤数据
                if (StringUtils.isNotNull(currentUser) && !currentUser.isAdmin())
                {
                    dataScopeFilter(joinPoint, currentUser, controllerDataScope.deptAlias(),
                            controllerDataScope.userAlias());
                }
            }
        }
    
        /**
         * 数据范围过滤
         *
         * @param joinPoint 切点
         * @param user 用户
         * @param userAlias 别名
         */
        public static void dataScopeFilter(JoinPoint joinPoint, SysUser user, String deptAlias, String userAlias)
        {
            StringBuilder sqlString = new StringBuilder();
    
            for (SysRole role : user.getRoles())
            {
                String dataScope = role.getDataScope();
                if (DATA_SCOPE_ALL.equals(dataScope))
                {
                    sqlString = new StringBuilder();
                    break;
                }
                else if (DATA_SCOPE_CUSTOM.equals(dataScope))
                {
                    sqlString.append(StringUtils.format(
                            " OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = {} ) ", deptAlias,
                            role.getRoleId()));
                }
                else if (DATA_SCOPE_DEPT.equals(dataScope))
                {
                    sqlString.append(StringUtils.format(" OR {}.dept_id = {} ", deptAlias, user.getDeptId()));
                }
                else if (DATA_SCOPE_DEPT_AND_CHILD.equals(dataScope))
                {
                    sqlString.append(StringUtils.format(
                            " OR {}.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set( {} , ancestors ) )",
                            deptAlias, user.getDeptId(), user.getDeptId()));
                }
                else if (DATA_SCOPE_SELF.equals(dataScope))
                {
                    if (StringUtils.isNotBlank(userAlias))
                    {
                        sqlString.append(StringUtils.format(" OR {}.user_id = {} ", userAlias, user.getUserId()));
                    }
                    else
                    {
                        // 数据权限为仅本人且没有userAlias别名不查询任何数据
                        sqlString.append(" OR 1=0 ");
                    }
                }
            }
    
            if (StringUtils.isNotBlank(sqlString.toString()))
            {
                Object params = joinPoint.getArgs()[0];
                if (StringUtils.isNotNull(params) && params instanceof BaseEntity)
                {
                    BaseEntity baseEntity = (BaseEntity) params;
                    baseEntity.getParams().put(DATA_SCOPE, " AND (" + sqlString.substring(4) + ")");
                }
            }
        }
    
        /**
         * 拼接权限sql前先清空params.dataScope参数防止注入
         */
        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, "");
            }
        }
    }

     

  10. 如果数据权限控制不做改变可直接在sql语句中写死。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表