# 简易权限系统security **Repository Path**: rikuasoby/security ## Basic Information - **Project Name**: 简易权限系统security - **Description**: 简易权限系统 springboot + vue 插拔式不侵入用户数据 可进行菜单管理 接口管理 角色管理 接口鉴权 快速解决垂直越权问题 也可作为系统框架后续开发 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 4 - **Forks**: 0 - **Created**: 2021-05-15 - **Last Updated**: 2024-12-30 ## Categories & Tags **Categories**: Uncategorized **Tags**: Java, SpringBoot, Vue ## README #### 系统概述 简易权限系统仅用于 1.快速解决菜单,接口,角色的配置管理功能 2.用户接口调用时的鉴权,只限制垂直越权.水平越权请自行设计实现. 3.可绑在网关服务上进行鉴权,也可单独部署作为权限管理服务,对外提供权限接口 由于各系统用户业务数据不一,故此系统不侵入用户数据管理与登陆验证,只为节省公共功能的开发时间. #### 接入前提 1.接入系统自身采用SSM架构 2.已实现用户数据管理与登陆功能 #### 查看方式 1.下载项目打开 2.执行docs中的init_tables.sql初始化数据表,更改properties中的数据库连接信息 3.启动demo服务,访问http://localhost:8080/index.html #### 接入方式 1.如demo方式引入security或者直接代码拷贝到自己服务中 2.配置文件中需要为classpath*,以确保读取到security的mapper.xml文件 ``` mybatis.mapper-locations=classpath*:*mappers/**/*Mapper.xml ``` 3.实现SeExternalUserService接口(必须) 接入系统必须实现SeExternalUserService接口方法,提供 ​ 1.对用户的查询功能 ​ 2.获取当前操作人编号,姓名 以便security系统调用. ``` /** * 加载人员查询功能,必须实现 * Created by NANC on 2021/6/12. */ public interface SeExternalUserService { /** * 权限系统用于添加用户时,对用户数据的查询,需自定义实现 * @param userIdOrName * @return */ List searchUser(String userIdOrName); /** * 获取当前人员,权限页面操作时调用 * @return */ SeUserParam getNowUser(); } ``` 4.实现SeAuthorityService接口(可选) 实现此接口的方法后,即开启security的自动鉴权,通过filter在调用时对接口权限进行判断. 权限不足时会抛出SeSecurityFailException,接入系统需自行捕获后处理. ``` /** * 实现此接口,buildServicePath进行服务加载即使用自动权限校验功能 */ public interface SeAuthorityService { /** * 系统启动时会按serviceCode载入这些service的api列表,当接口调用时,如果url地址存在于载入的api列表, * 就会去取getPathsFromCache的个人权限进行比对拦截 * 如果service的部分接口地址不需要拦截,就不要把接口配到菜单里 * 如果整个service的接口都不需要拦截,此处就不要build进来 * @return */ String[] buildServicePath(); /** * 白名单的不进行拦截,当然buildServicePath规定之外的路径本身就不会拦截。 * 1.指定对build进来的service的接口,其中哪些不需要拦截 2.有些整体不需要拦截的可通过白名单避免多余无效的匹配过程 * @return */ String[] buildWhiteList(); /** * 实现登录功能时,请手动调用SeCommonService.getApiSecurityForLogin会返回员工有权限的接口路径列表,请自行将列表存储缓存,并重写此方法取出 * security会在每次接口调用时,过滤器回调此方法获取员工权限进行比对,建议从缓存获取 * @return */ Set getPathsFromCache(); /** * 当进行接口调用时,告诉系统当前的api地址属于哪个service,可通过threadlocal或者session返回 * 如果不告知,会对载入的所有service的地址进行比对,会多耗时间 * 例:此处传security,调用接口时就会将url与security服务的api列表比对,若存在则接下来需要去判断用户权限,不存在则不需要判断权限 * @return */ String getCurrentServiceCode(); } ``` #### 系统操作 项目启动后访问 http://localhost:8080/index.html 如接入系统有自身过滤器,注意放开拦截 权限管理下的菜单均属于security服务 ![](docs/1.png) #### 接口限权 对接口操作进行权限控制 参看接入方式-4.实现SeAuthorityService接口 在接口SeAuthorityService的实现类中载入security ``` /** * 系统启动时会按serviceCode载入这些service的api列表 * @return */ @Override public String[] buildServicePath() { String []codes = {"security","test"}; return codes; } ``` 用户登录时调用以下方法获取当前用户在security下的api权限列表 ※1为测试数据的userId ``` seCommonService.getApiSecurityForLogin("1","security") ``` 给用户1 授权全局管理员权限,全局管理员权限如下,将菜单管理的查询接口取消勾选 ![](docs/2.png) 访问菜单管理,调用查询接口时提示权限不足 ※非权限系统接口(非/se开头的接口地址),抛出SeSecurityFailException,需接入系统在SeAuthorityFilter过滤器外套一层统一处理 ![](docs/3.png) #### 权限分配 给用户2授权服务管理员权限,服务管理员权限如下 ![](docs/4.png) 给用户2授权为外部服务的管理员 ![](docs/5.png) 模拟登陆用户2,重启系统 ``` @Override public SeUserParam getNowUser() { // 模拟当前登录人是2 SeUserParam user1 = new SeUserParam(); user1.setUserId("2"); user1.setUserName("南尘"); return user1; } ``` 用户2即可在权限系统为外部服务配置菜单以及分配权限 ![](docs/6.png) #### 系统扩展 作为简易系统框架使用 将外部服务分配给用户1,在index.html中同时获取security与test的菜单 ``` axios.get('/se/common/selectSecurityMenu', { params: { serviceCode: 'security,test', tree: '1' } }) ``` 在routes中配置helloworld地址,新建helloworld.vue ``` const routes = [ { name: 'service', path: '/service', component: httpVueLoader('component/service.vue') }, { name: 'menu', path: '/menu', component: httpVueLoader('component/menu.vue') }, { name: 'role', path: '/role', component: httpVueLoader('component/role.vue') }, { name: 'user', path: '/user', component: httpVueLoader('component/user.vue') }, { name: 'helloworld', path: '/helloworld', component: httpVueLoader('component/helloworld.vue') } ]; ``` 在菜单中配置路径 ![](docs/7.png) 即可访问到自定义页面 ![](docs/8.png)