基于Springboot实现权限管理系统(RBAC)
概述
详细
操作步骤
0>将项目导入到idea中
1>新建mysql数据库rbac,将 rbac.sql 脚本数据导入
2>修改:application.properties 中数据库配置账号密码
3>运行App.java类,启动程序
4>访问http://localhost:8080 默认账号密码为:admin/1,测试用户: zhangsan/1
核心概念(来自百度百科)
RBAC:基于角色的访问控制,是面向企业安全策略的一种有效的访问控制方式,其基本思想是,对系统操作的各种权限不是直接授予具体的用户,而是在用户集合与权限集合之间建立一个角色集合,每一种角色对应一组相应的权限,一旦用户被分配了适当的角色后,该用户就拥有此角色的所有操作权限。这样做的好处是,不必在每次创建用户时都进行分配权限的操作,只有分配用户响应的角色即可,而且角色的权限变更必用户的权限变更要少得多,这样将简化用户的权限管理,减少系统的开销。
简单说:用户扮演某个角色,被允许执行某些操作。 比如:用户充值成为SVIP,可以下载苍老师高清无码教育影片。
员工:代指某个用户,系统是以企业内部项目为例子,操作主体就是员工,这里理解为用户
角色:权限的集合,一个角色包含多种操作权限,一个员工可扮演多种角色,是多对多关心。
权限:允许对资源的操作抽象,rbac中权限就是对资源的crud操作。比如:员工添加, 部门删除等。
表设计
实现原理
在javaweb中权限的控制,其实就是对请求映射方法控制,如果登录用户有这个权限,允许访问,如果没有权限,不允许访问。居于这个原理,rbac实现步骤如下:
1>自定义一个权限注解:@RequiredPermission,约定贴有这个注解映射方法,必须进行权限校验
2>在需要进行权限校验的请求映射方法中贴上这个这个注解
3>使用拦截器对所有请求进行拦截,每次访问是进行权限校验。
4>如果使用admin登录,不需要拦截
项目结构
核心代码
自定义注解
@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; } }
操作效果
登录
员工,权限,角色列表
角色,员工编辑页面
没有权限的操作
好了,到这就结束啦,祝好!