栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

后台管理系统 -- 行权限与列权限的设计与实现

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

后台管理系统 -- 行权限与列权限的设计与实现

开篇说明
  • 如果在这里获得过启发和思考,希望点赞支持!对于内容有不同的看法欢迎来信交流。
  • 技术栈 >> java
  • 邮箱 >> 15673219519@163.com
描述
  • 后台系统中除了根据角色分配不同的菜单,还经常遇到在一菜单中,不同角色或者不同的人员拥有不同的查选权限。
  • 查询权限又可以分为行查询,列查询。行查询实现起来比较简单,下面会简单列出我遇到到的方法;然而列权限似乎没有看到一个很好的实现方法,并且实现起来比较复杂,导致无从下手。
  • 接下来,我将具体描述我在系统中的实现方式。包括对行权限,列权限。
我的思路
  • 行权限
    • 1 通常可以通过过滤器,或者AOP等过滤掉角色或者用户没有权限查询的数据。(推荐)
    • 2 也可以在搜索添加中限制只能填写有权限的搜索条件。(不推荐,该方式是可以进行绕过的)
  • 列权限,操作权限
    • 1 对于角色权限种类多的情况,我们可以通过在数据库记录每个角色在每个页面拥有的列,以及可以操作的功能实现列权限功能。 (推荐)
    • 2 当需要区分的角色权限种类不多时,可以为不同角色编写不同的页面。这种方式仅仅适合角色不多的情况,否则开发维护成本太大。(不推荐)
行权限(提供实现的思路,具体部分细节需要根据不同项目实际情况)
  • 实现目标: 涉及到的相关需要行权限的查询只要添加自定义注解@SearchPermissions就可以过滤掉没有权限的数据。如下:
@SearchPermissions
@PostMapping("/get/page")
public MSG> getListForPage(@RequestBody UserSearchDto searchDto){
    // TODO
    return MSG.SUCCESS();
}
  • 创建自定义注解
    SearchPermissions.java
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@documented
public @interface SearchPermissions {
}

SearchPermissionsAspect.java

@Slf4j
@Aspect
@Component
public class SearchPermissionsAspect {

    @Pointcut("@annotation(com.qykj.admin.aspect.SearchPermissions)")
    public void pointcut() {}

    @Before("pointcut()")
    public void process(JoinPoint point){
        // 1,TODO 通过请求获取当前请求的用户角色,查询到其有哪些查询权限
        
        // 2,TODO 通过point获取用户查询的条件,一般会将相关的涉及到权限控制的查询字段封装公共的基类,便于在此处操作
        
        // 3,过滤掉,该用户没有的查询条件,即可
        }
    }
}

列权限(提供实现的思路,具体部分细节需要根据不同项目实际情况)
  • 实现目标: 涉及到的相关需要列权限,操作权限的查询只要添加自定义注解@FieldFilter(javaType = User.class, name = "user_list@view")就可以过滤掉没有权限的数据。如下:
@SearchPermissions
@FieldFilter(javaType = UserParent.class, name="name = "user_list@view")
@PostMapping("/get/page")
public MSG> getListForPage(@RequestBody UserSearchDto searchDto){
    // TODO
    return MSG.SUCCESS(listForPage);
}
  • 创建自定义注解
    FieldFilter.java
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@documented
public @interface FieldFilter {
    
    // 需要过滤的类  User.class过滤掉的是User类中的字段
    Class javaType() default Object.class;
    
    // 此处用于标识该请求是控制那也页面的列权限还是操作权限 (user_list@view 用户列表列权限),(user_list@opt 用户列表操作权限)
    String name() default "";
}
@Aspect
@Component
public class FieldFilterAspect {

    @Pointcut("@annotation(com.qykj.admin.aspect.FieldFilter)")
    public void fieldFilterAspect(){}
    
    @Around("fieldFilterAspect()")
    public MSG around(JoinPoint point) throws Throwable {
        // 1,TODO 通过请求获取当前请求的用户角色ID
        
        // 2,TODO 通过point获取controller方法 @FieldFilter(javaType = User.class, name = "user_list@view"),即可知道那个页面的操作
        
        // 3,TODO 通过 user_list@view + 角色ID 即可从数据库中获取可以返回那些字段那些操作权限
        
        // 4,TODO 通过JSON序列化时,只序列化有权限的字段即可
        
        return MSG;
    }
}

总结
  • user_list@view中user_list对应页面菜单view标识是查询列。这些完全可以自定义,主要实现TODO中的思路步骤即可实现。
  • 列权限在本例中主要利用的JSON序列化,动态只序列化有权限的字段实现。还需要前端配合,根据你返回的字段渲染表单。为了确保查询为空的时候前端能够正确渲染表头,后端需要提供根据菜单标识查询有哪些字段的接口。
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/605657.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号