eladmin框架之权限控制

     开始写之前:最近几个月一直在研究eladmin框架,在eladmin基础上实现自己的系统,由于这个开源框架的易用性和高效率,导致我并没有理解透彻框架本身,只是照葫芦画瓢的去做,几个月做下来学到的知识微乎其微。以前我也没有记录的习惯,即使遇到一个BUG,百度完了解决了,下次遇到同样的BUG还是同样是去百度解决,基于此,为了养成一个好的学习习惯,以后我要将学到的知识,遇到的问题,都记录于此,以供自己复盘和积累经验。

   新的一天开始啦———————————————————————————————————

   eladmin系统权限控制采用的是RBAC思想,由此构成“用户—权限—菜单”的授权模型,在这种模型中,用户与权限,权限与菜单之间构成了多对多的关系。eladmin系统采用的安全框架是Spring Security + Jwt Token,访问后端接口需在请求头中携带token进行访问,请求头格式如下:

1.Spring Security是什么?

   Spring Security是一个专注于为Java应用程序提供身份验证和授权、访问控制的框架。

   原理:创建大量的过滤器filter和拦截器interceptor来进行请求的验证和拦截,以此达到安全。

2.JWT(Json Web Tokens)是什么?

   JWT是一种开放标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间作为JSON对象安全地传输信息。

   JWT的基本原理,基本流程如下:

   (1)客户端使用账号和密码请求登录接口;

   (2)登录成功后服务器使用签名密钥生成JWT,然后返回JWT给客户端;

   (3)客户端再次像服务端请求其他接口时会带上JWT;

   (4)服务器收到JWT后验证签名的有效性,对客户端做出相应的响应。

   JWT的基本数据结构:它是由 Header(头部), PayLoad(负载),Signature(签名)组成的。

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoia29uZ3poaSIsImlhdCI6MTU0Mzc1MzczNX0.h1XmQo017udxlFsH-8US9Lg8dJ0IDsSbRbjEN5Nq0l4

3. 数据交互流程如下:

    用户登录 -> 后端验证登录返回 token -> 前端带上token请求后端数据 -> 后端返回数据。

4.权限注解:

   eladmin框架中Spring Security提供了Spring EL表达式,允许我们在定义接口访问的方法上面添加注解,来控制访问权限。下面的接口表示用户拥有admin、menu:edit权限中的任意一个就能能访问update方法, 如果方法不加@preAuthorize注解,意味着所有用户都需要带上有效的token后能访问update方法。

@Log(description = "修改菜单")
@PutMapping(value = "/menus")
@PreAuthorize("hasAnyRole('admin','menu:edit')")
public ResponseEntity update(@Validated @RequestBody Menu resources){
    // 略
}

   由于每个接口都需要给超级管理员放行,而使用hasAnyRole('admin','user:list')每次都需要重复的添加 admin 权限,因此在新版本 (2.3) 中加入了自定义权限验证方式,在验证的时候默认给拥有admin权限的用户放行。

/**
 * 自定义权限验证方式,在验证的时候默认给拥有admin权限的用户放行
 * @author Zheng Jie
 */
@Service(value = "el")
public class ElPermissionConfig {

    public Boolean check(String ...permissions){
        // 获取当前用户的所有权限
        List<String> elPermissions = SecurityUtils.getCurrentUser().getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList());
        // 判断当前用户的所有权限是否包含接口上定义的权限
        return elPermissions.contains("admin") || Arrays.stream(permissions).anyMatch(elPermissions::contains);
    }
}

 使用方式:

@PreAuthorize("@el.check('user:list','user:add')") 

  接口放行:

  有些接口是不需要验证权限的,这个时候就需要我们给接口放行,使用方式如下:

(1)使用注解方式:只需要在Controller的方法上加入该注解即可

@AnonymousAccess

 

分割线————————————————————————————————————————

当我在页面想自己实现权限控制的时候,SecurityUtils是一个很有用的类,这个类中定义了获取当前登录的用户的相关信息可以供我们在查询时添加条件以此实现对数据显示的权限控制,因为目前框架实现的是对菜单、增删改查的控制,所以当我们想对前端显示的数据根据不同角色进行控制时,就可以在前端通过JPA的criteria查询增加条件实现,但需要注意的是,比如同时有两个条件时,查询的是两个条件的并集,如果查询两个条件的交集,还需要在serviceImpl中自定义实现:

controller层先将criteria进行赋值,service层查询时就会查=该条件的值

并集:

@GetMapping(value = "/user")
    @ApiOperation("用户日志查询")
    public ResponseEntity<Object> queryUserLog(LogQueryCriteria criteria, Pageable pageable){
        criteria.setLogType("INFO");
        criteria.setBlurry(SecurityUtils.getCurrentUsername());
        return new ResponseEntity<>(logService.queryAllByUser(criteria,pageable), HttpStatus.OK);
    }


 @Override
    public Object queryAllByUser(LogQueryCriteria criteria, Pageable pageable) {
        Page<Log> page = logRepository.findAll(((root, criteriaQuery, cb) -> QueryHelp.getPredicate(root, criteria, cb)), pageable);
        return PageUtil.toPage(page.map(logSmallMapper::toDto));
    }

 交集:

@Override
    public Map<String, Object> findByCurrentUser(AllResourcesDto query, Pageable pageable) {
        Sort sort = Sort.by(Sort.Direction.DESC, "id");
        List<Requirement> requirements = requirementRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder),sort);
        List<RequirementDto> requirement = new ArrayList<>();
        String username = criteria.getCreateBy();
        String deptname = criteria.getDeptName();
        for (int i=0; i<requirements.size(); i++){
            if (requirements.get(i).getCreateBy().equals(username) || requirements.get(i).getDept().getName().equals(deptname) ){

                    requirement.add(requirementMapper.toDto(requirements.get(i)));
                    Long requirementId = requirements.get(i).getId();
                    List<String> projectName = requirementRepository.findProjectName(requirementId);
                    String projectNames = "";
                    for (int j=0; j<projectName.size(); j++){
                        projectNames += projectName.get(j)+".";
                    }
                    requirement.get(requirement.size()-1).setProjectNames(projectNames);
                }

        }
        return PageUtil.toPage(
                PageUtil.toPage(pageable.getPageNumber(),pageable.getPageSize(), requirement),
                requirement.size()
        );
	}

当我们想根据当前用户的等级控制前端可编辑字段时,我们可以在后端获取当前用户的等级并传递给前端,前端通过函数取得当前用户的等级后,在form表单中根据等级数据进行可编辑控制:

@Override
    public int getPower() {
        List<Integer> levels = roleService.findByUsersId(SecurityUtils.getCurrentUserId()).stream().map(RoleSmallDto::getLevel).collect(Collectors.toList());
        int min = Collections.max(levels);
        return min;
    }


@ApiOperation("获取权限值")
    @AnonymousPostMapping("/getPowers")
    @AnonymousAccess
    public ResponseEntity<Object> getPowers(){
        return new ResponseEntity<>(requirementService.getPower(), HttpStatus.OK);
    }
getPowers() {
        let form = new FormData();
        axios({
          method: "post",
          url: "/api/requirements/getPowers",
          headers: {
            "Content-type": "multipart/form-data",
            Authorization: getToken(),
          },
          data: form,
        }).then(
          (res) => {
            this.power = res.data
          },
          (err) => {
          }
        );
      },


[CRUD.HOOK.beforeRefresh](crud, form) {
        this.getPowers()
      },
<el-form-item label="备注" width="125" prop="comments">
<el-input type="textarea" autosize v-model="form.comments" :disabled="power>2 && grant === 0"/>
</el-form-item>

 

 

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: eladmin是一款基于springboot + vue 前后端分离的开源快速开发平台,它采用了最新的前端技术栈,支持多种登录方式,拥有完善的接口文档及自动化测试,可以帮助开发者更快捷的搭建一个企业级中后台产品。diboot是一个基于Springboot的快速开发框架,它提供了一系列的功能,例如快速构建后台管理系统、快速实现数据库操作、简洁的权限控制、RESTful API封装、灵活的组织机构配置等,可以帮助开发者快速构建一个中后台产品。 ### 回答2: Eladmin框架是一种基于Spring Boot和Vue的开源后台管理系统框架。它提供了丰富的功能和灵活的配置选项,可以快速开发出高质量和易于维护的后台管理系统。 Eladmin框架的主要特点有以下几点: 1.权限管理:Eladmin框架提供了灵活的用户、角色和权限管理功能,可以根据实际需求进行配置和扩展。 2.代码生成器:Eladmin框架内置了代码生成器,可以根据数据库表结构自动生成基础的增删改查接口和前端代码,大大提高了开发效率。 3.多租户支持:Eladmin框架支持多租户模式,可以为不同的租户提供定制化的功能和界面。 4.日志管理:Eladmin框架提供了日志管理功能,可以记录用户的操作日志,方便追溯和审计。 5.数据可视化:Eladmin框架集成了Echarts图表库,可以简单地生成各种图表,帮助用户实时监控和分析数据。 Diboot框架是一种基于Spring Boot的开源快速开发框架。它采用了轻量级、模块化和灵活的设计理念,致力于提供更简单、高效和易于扩展的开发体验。 Diboot框架的主要特点有以下几点: 1.简化开发:Diboot框架提供了一系列的简化开发工具,例如注解、代码生成器和模板引擎等,可以大大减少开发工作量。 2.灵活配置:Diboot框架支持灵活的配置选项和可插拔的模块,可以根据实际需求进行定制和扩展。 3.强大的数据绑定:Diboot框架支持强大的数据绑定功能,可以将前端请求参数与后端实体对象进行自动映射,大大简化了数据处理的过程。 4.多数据库支持:Diboot框架可以很好地支持多种数据库,如MySQL、Oracle和SQL Server等,开发人员可以根据需求选择适合的数据库进行开发。 5.安全性和稳定性:Diboot框架对安全性和稳定性的要求非常高,采用了一系列的安全机制和异常处理策略,保证了系统的可靠性和可扩展性。 总的来说,Eladmin框架和Diboot框架都是优秀的开源框架,它们提供了丰富的功能和便捷的开发工具,可以帮助开发人员快速构建高质量的后台管理系统和业务应用。 ### 回答3: eladmin框架是一款基于Spring Boot和Spring Security开发的开源后台管理系统。它提供了一套快速构建后台管理系统的解决方案,包含了用户管理、角色管理、菜单管理、日志管理等常用功能模块。eladmin框架还集成了代码生成器,可以根据数据库表结构自动生成前后端代码,大大提高了开发效率。 eladmin框架采用前后端分离的架构,前端使用了Vue.js框架、ElementUI组件库等技术,实现了响应式的管理界面。同时,eladmin框架提供了丰富的API接口,方便客户端进行数据的交互和访问。 另外,eladmin框架还实现了权限管理功能,可以灵活地定义角色和权限,并进行精确的访问控制。它还内置了日志管理功能,可以对系统的操作日志进行记录和查看,方便系统的监控和追踪。 diboot框架是一款基于Spring Boot开发的低代码开发框架,旨在提高开发效率和代码质量。diboot框架采用了注解驱动的开发方式,通过减少手写重复代码的方式,大大简化了开发流程。 diboot框架提供了一套简洁易用的API接口,可以轻松实现数据的增删改查操作。它支持多种数据库类型,包括MySQL、Oracle、SQL Server等,并提供了数据库操作的封装,方便开发人员进行数据库的操作和管理。 diboot框架还提供了权限管理功能,可以根据角色和权限进行精确的访问控制。同时,diboot框架支持多租户架构,可以为不同的租户提供独立的数据和功能,满足多租户场景的需求。 总的来说,eladmin框架和diboot框架都是基于Spring Boot开发的高效开发框架,它们都提供了丰富的功能和易用的API接口,可以帮助开发人员快速构建高质量的后台管理系统。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值