作者:仔仔衰才_887 | 来源:互联网 | 2023-12-14 16:11
本文详细介绍了SpringBoot中实现uri统一权限管理的方法,包括表结构定义、自动统计URI并自动删除脏数据、程序启动加载等步骤。通过该方法可以提高系统的安全性,实现对系统任意接口的权限拦截验证。
文章目录
- SpringBoot uri统一权限管理
- 1. 表结构定义
- 2. 自动统计URI,并自动删除脏数据
- 3. 程序启动加载
- 4. 结果
- 5. 其他
SpringBoot uri统一权限管理
业务需求:为了增加系统的安全性,系统的任意一个接口均要做权限拦截验证。
1. 表结构定义
CREATE TABLE `sys_uri` (`id` bigint(11) NOT NULL AUTO_INCREMENT COMMENT 'id',`bean_name` varchar(128) DEFAULT NULL COMMENT 'controller类名',`uri` varchar(256) DEFAULT NULL COMMENT '访问地址',`clazz_name` varchar(256) DEFAULT NULL COMMENT '类名',`create_time` datetime DEFAULT NULL COMMENT '创建时间',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=44 DEFAULT CHARSET=utf8 COMMENT='系统uri记录表';CREATE TABLE `role_uri_authority` (`id` bigint(11) NOT NULL AUTO_INCREMENT COMMENT 'id 自增',`role_id` bigint(11) NOT NULL COMMENT '角色id,对应角色表roles主键',`sys_uri_id` bigint(11) NOT NULL COMMENT 'sys_uri表中的主键id',PRIMARY KEY (`id`),KEY `role_id` (`role_id`),KEY `sys_uri_id` (`sys_uri_id`)
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8 COMMENT='角色uri权限访问表';
2. 自动统计URI,并自动删除脏数据
直接上service,
@Service
public class UriInitServiceImpl implements UriInitService {// 排除swagger与其他内置的uri;排序用户登录模块,以及内部测试模块controllerprivate static final List<String> excludesControllerList &#61;Stream.of("apiResourceController", "knife4jController", "basicErrorController", "loginController", "thymeleafTest", "testController").collect(Collectors.toList());// SpringBoot 内置对象,可获取controller所有的uri信息&#64;Autowiredprivate RequestMappingHandlerMapping requestMappingHandlerMapping;// 逆向工程自动生成dao&#64;Autowiredprivate RoleUriAuthMapperExt roleUriAuthMapperExt;// 逆向工程自动生成dao&#64;Autowiredprivate SysUriMapperExt sysUriMapperExt;private Date sysDate;&#64;Transactional&#64;Overridepublic void initSysUri() {// 全量uriList<SysUri> sysUriList &#61; new ArrayList<>();sysDate &#61; new Date();// 获取系统所有的uri信息Map<RequestMappingInfo, HandlerMethod> handlerMethodsMap &#61; requestMappingHandlerMapping.getHandlerMethods();for (Map.Entry<RequestMappingInfo, HandlerMethod> item : handlerMethodsMap.entrySet()) {saveUriMap(sysUriList, item);}// 原有的存量数据List<SysUri> oldSysUriList &#61; sysUriMapperExt.selectByExample(new SysUriExample());// sysUriList - oldSysUriList 新增差集List<SysUri> addSysUriList &#61; sysUriList.stream().filter(s -> !oldSysUriList.stream().map(os -> os.getUri()).collect(Collectors.toList()).contains(s.getUri())).collect(Collectors.toList());// oldSysUriList - sysUriList 移除差集List<Long> reduceSysUriIdList &#61; oldSysUriList.stream().filter(os -> !sysUriList.stream().map(s -> s.getUri()).collect(Collectors.toList()).contains(os.getUri())).map(item -> item.getId()).collect(Collectors.toList());// sysUri 新增if (!CollectionUtils.isEmpty(addSysUriList)) {sysUriMapperExt.batchInsert(addSysUriList);}// sysUri,roleUriAuth删除已清除的uriif (!CollectionUtils.isEmpty(reduceSysUriIdList)) {SysUriExample example &#61; new SysUriExample();example.createCriteria().andIdIn(reduceSysUriIdList);sysUriMapperExt.deleteByExample(example);RoleUriAuthExample roleUriAuthExample &#61; new RoleUriAuthExample();roleUriAuthExample.createCriteria().andSysUriIdIn(reduceSysUriIdList);roleUriAuthMapperExt.deleteByExample(roleUriAuthExample);}}// 过滤映射转换private void saveUriMap(List<SysUri> sysUriList, Map.Entry<RequestMappingInfo, HandlerMethod> item) {RequestMappingInfo uriMappingInfo &#61; item.getKey();HandlerMethod value &#61; item.getValue();String uri &#61; uriMappingInfo.getPatternsCondition().toString();// 类名:xxxControllerString beanName &#61; value.getBean().toString();// clazz全路径名称String clazzName &#61; value.getBeanType().getName();if (!excludesControllerList.contains(beanName)) {SysUri sysUri &#61; new SysUri();sysUri.setBeanName(beanName);sysUri.setUri(uri);sysUri.setClazzName(clazzName);sysUri.setCreateTime(sysDate);sysUriList.add(sysUri);}}
}
3. 程序启动加载
&#64;Service
public class StartupListener implements ApplicationListener<ContextRefreshedEvent> {private Logger logger &#61; LoggerFactory.getLogger(StartupListener.class);&#64;Autowiredprivate UriInitService uriInitService;/*** 触发机制* 容器中所有的bean初始化完成之后执行** &#64;param evt*/&#64;Overridepublic void onApplicationEvent(ContextRefreshedEvent evt) {try {// 保证只执行一次if (evt.getApplicationContext().getParent() &#61;&#61; null) {// 程序启动初始化uriuriInitService.initSysUri();}} catch (Exception e) {logger.error("onApplicationEvent error {}", e.getMessage());// 异常 强制关闭启动throw new RuntimeException(e.getMessage());}}}
4. 结果
5. 其他
以上为各个系统通用模块。
其他拦截器验证业务&#xff0c;缓存等代码根据自身系统开发。