框架模块说明 #05 权限管理_03

背景

权限设计可以分为两个主要方面:操作权限数据权限 。前两篇文章已经详细介绍了操作权限的设计与实现,以及如何将其与菜单关联起来的具体方法。本篇将聚焦于数据权限,为您深入讲解相关的设计与实现方式。

全局开关

复制代码
@Value("${system.DataDimension.open:false}")  // 全局开关,是否开通数据权限,默认为关闭
private Boolean isSystemDataDimensionOpen;

权限配置

配置数据权限时,可以配置两种类型的,一种是配置给角色,考虑到数据权限有可能是针对不同的用户的情况,所以也可以配置给指定用户,其实前面登录时讲过了登录时数据权限加载的一些内容,

数据字典

权限配置

角色数据权限

用户数据权限

表结构

sql 复制代码
CREATE TABLE `t_frame_data_dimension` (
  `data_auth_list_id` bigint NOT NULL AUTO_INCREMENT,
  `data_dimension_type` int NOT NULL COMMENT '10:角色 20:用户数据权限',
  `refer_id` bigint NOT NULL COMMENT '根据权限类型来关系不用的ID',
  `data_dimension` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '权限维度:: org(组织机构) /  micro 微服务',
  `data_dimension_value` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '权限值',
  `status` int NOT NULL DEFAULT '1' COMMENT '状态,1/有效 0/无效 -1/过期',
  `create_by` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
  `create_date` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  `update_by` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
  `update_date` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`data_auth_list_id`) USING BTREE,
  UNIQUE KEY `udx_t_frame_data_dimension` (`data_dimension_type`,`refer_id`,`data_dimension`,`data_dimension_value`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='数据权限列表\r\n角色类型为功能权限之外的权限统一为功能权限';

注解类

在实际的业务中并不是每个方法都要数据权限的控制,于是首先我增加一个方法级的注解,用来标注是否需要校验数据权限。但是这个注解是专门来处理mapper.xml自定义标签的处理,

权限标签

我们将自定义标签"dataDimension",如下为自定义标签的示例:

XML 复制代码
<where>
          <![CDATA[
            1=1
              <dataDimension> [{"fieldName":"t_system_dic_master.belong_micro_service","dimensionName":"micro_service_name","operator":"="}] </dataDimension>
            ]]>
            <if test="params.dicMasterId!=null">
                dic_master_id = #{params.dicMasterId,jdbcType=BIGINT}
            </if>
            <if test="params.dicCode!=null">
                and dic_Code like CONCAT('%',#{params.dicCode,jdbcType=VARCHAR},'%')
            </if>
            <if test="params.dicName!=null">
                and dic_Name like CONCAT('%',#{params.dicName,jdbcType=VARCHAR},'%')
            </if>
            <if test="params.status!=null and params.status!=''">
                and t_system_dic_master.`status` = #{params.status,jdbcType=INTEGER}
            </if>
            <if test="params.belongMicroService!=null and params.belongMicroService!=''">
                and t_system_dic_master.belong_micro_service = #{params.belongMicroService,jdbcType=INTEGER}
            </if>

            <if test="params.dicItemCode!=null or params.dicItemName!=null or params.dicItemValue!=null">
                and exists(
                select 1 from t_system_dic_item dic_item
                where dic_item.dic_master_id = t_system_dic_master.dic_master_id
                <if test="params.dicItemCode!=null">
                    and dic_item.dic_item_code like CONCAT('%',#{params.dicItemCode,jdbcType=VARCHAR},'%')
                </if>
                <if test="params.dicItemName!=null">
                    and dic_item.dic_item_name like CONCAT('%',#{params.dicItemName,jdbcType=VARCHAR},'%')
                </if>
                <if test="params.dicItemValue!=null">
                    and dic_item.dic_item_value like CONCAT('%',#{params.dicItemValue,jdbcType=VARCHAR},'%')
                </if>
                )
            </if>
        </where>

Mybatis标签拦截器

由于代码量有点大,请稳步gitcode查看

GitCode - 全球开发者的开源社区,开源代码托管平台GitCode是面向全球开发者的开源社区,包括原创博客,开源代码托管,代码协作,项目管理等。与开发者社区互动,提升您的研发效率和质量。https://gitcode.com/YouYouLongLong/springcloud-framework/blob/master/core-common-parent/auth-common/src/main/java/org/cloud/dimension/mybatis/interceptor/DataDimensionInterceptor.java

UTIL类

由于现在一些类似于mybatisplus的框架大行其道,给mybatis的使用带来了很大的便利,当然同时也让程序员的sql脚本能力有所下降,基于这样的原因,那么业务中就要在java代码中控制数据权限了,我暂时没有想到好的办法,于是我提供DataDimensionUtil类进行数据权限的查询的功能,将数据权限获取后根据实际的业务需要进行处理。

java 复制代码
public class DataDimensionUtil {

    private DataDimensionUtil() {

    }

    private final static DataDimensionUtil dataDimensionUtil = new DataDimensionUtil();

    public static DataDimensionUtil single() {
        return dataDimensionUtil;
    }

    private RedisUtil redisUtil;


    public RedisUtil getRedisUtil() {

        if (redisUtil == null) {
            redisUtil = SpringContextUtil.getBean(RedisUtil.class);
        }
        return redisUtil;
    }

    public Map<String, Set<String>> getCurrentUserAllDataDimension() {
        final Long userId = RequestContextManager.single().getRequestContext().getUser().getId();
        return getRedisUtil().hashGet(CoreConstant.USER_LOGIN_SUCCESS_CACHE_KEY + userId, USER_DIMENSION_CACHE_KEY);
    }

    public Set<String> getCurrentUserDataDimensionByName(String DataDimensionName) {
        return getCurrentUserAllDataDimension().get(DataDimensionName);
    }

总结

本文围绕数据权限的设计与实现展开,结合实际开发场景,从全局控制、权限配置、表结构设计、注解类定义、自定义标签、MyBatis标签拦截器以及实用工具类等多个方面进行了全面介绍,旨在为开发者提供完整的数据权限实现方案。

通过上述设计,数据权限实现方案具备以下特点:

  • 灵活性:支持多维度配置(角色、用户)与动态权限规则加载。
  • 可扩展性:结合 MyBatis 拦截器与工具类,便于扩展和适配多种业务需求。
  • 高效性:利用缓存优化权限查询性能,减少数据库查询压力。
相关推荐
R6bandito_4 分钟前
Qt几何数据类型:QLine类型详解(基础向)
c语言·开发语言·c++·经验分享·qt
杭电码农-NEO7 分钟前
【lua语言基础(四)】IO模型以及补充知识
开发语言·junit·lua
是十一月末13 分钟前
Python语法之正则表达式详解以及re模块中的常用函数
开发语言·python·正则表达式
一只大侠15 分钟前
计算S=1!+2!+3!+…+N!的值:JAVA
java·开发语言
一只大侠17 分钟前
输入一串字符,以“?”结束。统计其中字母个数,数字个数,其它符号个数。:JAVA
java·开发语言·算法
以后不吃煲仔饭18 分钟前
面试小札:线程池
java·后端·面试
Oneforlove_twoforjob18 分钟前
【Java基础面试题011】什么是Java中的自动装箱和拆箱?
java·开发语言
优雅的落幕35 分钟前
多线程---线程安全(synchronized)
java·开发语言·jvm
Charlie__ZS36 分钟前
帝可得-设备管理
java·maven·intellij-idea·idea
小黄编程快乐屋37 分钟前
前端小练习——大雪纷飞(JS没有上限!!!)
开发语言·前端·javascript