SpringBoot uri统一权限管理

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;排序用户登录模块,以及内部测试模块controller
    private static final List<String> excludesControllerList =
            Stream.of("apiResourceController", "knife4jController", "basicErrorController", "loginController", "thymeleafTest", "testController").collect(Collectors.toList());

    // SpringBoot 内置对象,可获取controller所有的uri信息
    @Autowired
    private RequestMappingHandlerMapping requestMappingHandlerMapping;

	// 逆向工程自动生成dao
    @Autowired
    private RoleUriAuthMapperExt roleUriAuthMapperExt;

    // 逆向工程自动生成dao
    @Autowired
    private SysUriMapperExt sysUriMapperExt;

    private Date sysDate;

    @Transactional
    @Override
    public void initSysUri() {
        // 全量uri
        List<SysUri> sysUriList = new ArrayList<>();
        sysDate = new Date();
        // 获取系统所有的uri信息
        Map<RequestMappingInfo, HandlerMethod> handlerMethodsMap = requestMappingHandlerMapping.getHandlerMethods();
        for (Map.Entry<RequestMappingInfo, HandlerMethod> item : handlerMethodsMap.entrySet()) {
            saveUriMap(sysUriList, item);
        }

        // 原有的存量数据
        List<SysUri> oldSysUriList = sysUriMapperExt.selectByExample(new SysUriExample());

        // sysUriList - oldSysUriList 新增差集
        List<SysUri> addSysUriList = sysUriList.stream()
                .filter(s -> !oldSysUriList.stream()
                        .map(os -> os.getUri()).collect(Collectors.toList()).contains(s.getUri()))
                .collect(Collectors.toList());

        // oldSysUriList - sysUriList 移除差集
        List<Long> reduceSysUriIdList = 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删除已清除的uri
        if (!CollectionUtils.isEmpty(reduceSysUriIdList)) {
            SysUriExample example = new SysUriExample();
            example.createCriteria().andIdIn(reduceSysUriIdList);
            sysUriMapperExt.deleteByExample(example);

            RoleUriAuthExample roleUriAuthExample = new RoleUriAuthExample();
            roleUriAuthExample.createCriteria().andSysUriIdIn(reduceSysUriIdList);
            roleUriAuthMapperExt.deleteByExample(roleUriAuthExample);
        }

    }

    // 过滤映射转换
    private void saveUriMap(List<SysUri> sysUriList, Map.Entry<RequestMappingInfo, HandlerMethod> item) {
        RequestMappingInfo uriMappingInfo = item.getKey();
        HandlerMethod value = item.getValue();
        String uri = uriMappingInfo.getPatternsCondition().toString();
        // 类名:xxxController
        String beanName = value.getBean().toString();
        // clazz全路径名称
        String clazzName = value.getBeanType().getName();
        if (!excludesControllerList.contains(beanName)) {
            SysUri sysUri = new SysUri();
            sysUri.setBeanName(beanName);
            sysUri.setUri(uri);
            sysUri.setClazzName(clazzName);
            sysUri.setCreateTime(sysDate);
            sysUriList.add(sysUri);
        }

    }
}

3. 程序启动加载

@Service
public class StartupListener implements ApplicationListener<ContextRefreshedEvent> {

    private Logger logger = LoggerFactory.getLogger(StartupListener.class);


    @Autowired
    private UriInitService uriInitService;


    /**
     * 触发机制
     * 容器中所有的bean初始化完成之后执行
     *
     * @param evt
     */
    @Override
    public void onApplicationEvent(ContextRefreshedEvent evt) {

        try {
            // 保证只执行一次
            if (evt.getApplicationContext().getParent() == null) {

                // 程序启动初始化uri
                uriInitService.initSysUri();


            }
        } catch (Exception e) {
            logger.error("onApplicationEvent error {}", e.getMessage());
            // 异常 强制关闭启动
            throw new RuntimeException(e.getMessage());
        }

    }


}

4. 结果

在这里插入图片描述

5. 其他

以上为各个系统通用模块。
其他拦截器验证业务,缓存等代码根据自身系统开发。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值