基于Springboot实现权限管理系统(RBAC)

发布时间:2021-07-12
技术:SpringBoot2.4.3 + freemarker2.3 + jdk11 + mysql5.7

概述

一个纯手工编写的权限管理系统(rbac),学习本案例可以快速掌握rbac操作原理。学习本案例前,读者需要一定springboot springmvc mybatis freemarker java web相关知识点。

详细

操作步骤

0>将项目导入到idea中

image.png

1>新建mysql数据库rbac,将 rbac.sql 脚本数据导入

2>修改:application.properties 中数据库配置账号密码

3>运行App.java类,启动程序

4>访问http://localhost:8080  默认账号密码为:admin/1,测试用户: zhangsan/1


核心概念(来自百度百科)

RBAC:基于角色的访问控制,是面向企业安全策略的一种有效的访问控制方式,其基本思想是,对系统操作的各种权限不是直接授予具体的用户,而是在用户集合与权限集合之间建立一个角色集合,每一种角色对应一组相应的权限,一旦用户被分配了适当的角色后,该用户就拥有此角色的所有操作权限。这样做的好处是,不必在每次创建用户时都进行分配权限的操作,只有分配用户响应的角色即可,而且角色的权限变更必用户的权限变更要少得多,这样将简化用户的权限管理,减少系统的开销。


简单说:用户扮演某个角色,被允许执行某些操作。 比如:用户充值成为SVIP,可以下载苍老师高清无码教育影片。


员工:代指某个用户,系统是以企业内部项目为例子,操作主体就是员工,这里理解为用户

角色:权限的集合,一个角色包含多种操作权限,一个员工可扮演多种角色,是多对多关心。

权限:允许对资源的操作抽象,rbac中权限就是对资源的crud操作。比如:员工添加, 部门删除等。


表设计

image.png


实现原理

在javaweb中权限的控制,其实就是对请求映射方法控制,如果登录用户有这个权限,允许访问,如果没有权限,不允许访问。居于这个原理,rbac实现步骤如下:

1>自定义一个权限注解:@RequiredPermission,约定贴有这个注解映射方法,必须进行权限校验

2>在需要进行权限校验的请求映射方法中贴上这个这个注解

3>使用拦截器对所有请求进行拦截,每次访问是进行权限校验。

4>如果使用admin登录,不需要拦截


项目结构

image.pngimage.png


核心代码

自定义注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequiredPermission {
    String name();
    String expression();
}

需要进行权限校验请求映射方法

@RequiredPermission(name="员工查询", expression = "employee:list")
@RequestMapping("list")
public String list(Model model, @ModelAttribute("qo") EmployeeQuery qo) {
    model.addAttribute("pageInfo", employeeService.query(qo));
    return "employee/list";
}

权限拦截器

@Configuration
public class CheckPermissionInterceptor implements HandlerInterceptor {
    // 进行权限判断
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 获取当前访问用户
        Employee employee = UserContext.getEmployee();
        if (employee.isAdmin()) { // 是管理员
            return true;
        }

        // HandlerMethod 是 Spring MVC 会使用这个类的对象进项目所有控制器处理方法进行封装
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        // 获取访问的处理方法上的注解
        RequiredPermission anno = handlerMethod.getMethodAnnotation(RequiredPermission.class);
        // 去判断处理方法上是否贴了自定义注解
        if(anno == null){
            return true;
        }
        // 代码执行到这里 访问的处理方法贴自定义注解,需要权限控制器
        // 获取注解上的权限表达式, 和此员工所有具有权限表达式对比, 若包含放行访问
        String expression = anno.expression();
        List<String> expressions = UserContext.getExpressions();
        if(expressions.contains(expression)) {
            return true;
        }
        if(handlerMethod.hasMethodAnnotation(ResponseBody.class)){
            response.setContentType("application/json;charset=utf-8");
            response.getWriter().write("{\"success\":false, \"msg\":\"没有操作权限\"}");
            return false;
        }
        // 代码执行到这里 不包含这个处理方法访问权限
        // 当访问路径没有处理方法的路径跟其匹配, 认为是访问静态资源 交由 DefaultServletHttpRequestHandler 对象处理
        response.sendRedirect("/permission/noPermission");
        return false;
    }
}

操作效果

登录

image.png

员工,权限,角色列表

image.png

image.pngimage.png

角色,员工编辑页面

image.png


image.png

没有权限的操作

image.png好了,到这就结束啦,祝好!




本实例支付的费用只是购买源码的费用,如有疑问欢迎在文末留言交流,如需作者在线代码指导、定制等,在作者开启付费服务后,可以点击“购买服务”进行实时联系,请知悉,谢谢
手机上随时阅读、收藏该文章 ?请扫下方二维码