gateway-统一权限-认证

本文详细介绍了如何构建一个多平台权限控制的系统,包括基础名词概念、认证鉴权流程、数据库设计以及实现细节。系统采用RBAC模型,通过角色和资源进行权限控制,实现了基于角色和资源的访问控制。用户信息、企业信息、角色和资源的关系清晰,通过Spring Cloud Gateway进行权限的验证和过滤。认证流程涉及用户登录、角色和权限的匹配,确保了系统安全。
摘要由CSDN通过智能技术生成

int## 基础名词概念
**权限:**属于系统的安全范畴,权限管理实现对用户访问系统的控制,按照安全规则或者安全控制策略用户可以访问而且只能访问自己被授权的资源,主要包括用户身份认证和请求鉴权两部分,简称认证鉴权
认证判断一个用户是否为合法用户的处理过程,最常用的简单身份认证是系统通过核对用户输入的用户名和口令,看其是否与系统中存储的该用户的用户名和口令一致,来判断用户身份是否正确
在这里插入图片描述

鉴权:即访问控制,控制谁能访问那些资源;进行身份认证后需要分配权限可访问的系统资源,对于某些资源没有权限是无法访问的,如下图所示

在这里插入图片描述
权限控制:用户是某个角色、或拥有某个资源时,才可访问系统资源我们称之为权限控制,权限控制分为下列2类型:
基于角色
RBAC基于角色的访问控制是以角色为中心进行访问控制,比如:主体的角色为总经理可以查询企业运营报表,查询员工薪资信息等,访问控制流程如下:
在这里插入图片描述
基于资源
RBAC基于资源的访问控制,是以资源中心进行访问控制,企业中常用的权限管理方法,实现思路是:将系统操作的每个URL配置在资源表中,将资源对应到角色,将角色分配给用户,用户访问系统功能通过Filter进行过滤,过滤器获取到用户的url,只要访问的url是用户分配角色中的URL是用户分配角色的url则进行访问,其具体流程如下:
在这里插入图片描述
匿名资源:无需认证鉴权就可以访问的资源
公共资源:只需登录既可以访问的资源

多平台权限控制

xxxx作为一个SaaS平台,商家提供运营主体信息后,运营平台会为商家开通系统,各个商家平台都需要在运营平台的管理下去工作:
1、运营平台可以管理所有商家平台的企业信息
2、运营平台可以管理所有商家平台的资源信息
3、运营平台可以管理所有商家平台的角色信息
4、运营平台可以管理商家平台的用户信息

第二章 基础信息简介

在开始做权限开发之前我们需要看下权限设计的数据库结构:
在这里插入图片描述
通过上图,我们可以得到如下的信息:
一个企业可以有多个用户
一个用户可以有多个角色
一个角色可以有多个资源
这个是经典的权限设计,也就是:企业,用户,角色,资源通过它们可以来完成整个权限的控制。

企业信息

商家想申请入驻平台,首先在申请页面【也可以后端录入】进行信息填写,填写完成【运营平台】对商家资质进行审核,审核通过后商家即可入职使用,如图所示:

在这里插入图片描述
数据库结构设计

CREATE TABLE `tab_enterprise` (
  `id` bigint(18) NOT NULL,
  `enterprise_id` bigint(18) NOT NULL COMMENT '商户ID【系统内部识别使用】',
  `enterprise_name` varchar(200) COLLATE utf8_bin NOT NULL COMMENT '企业名称',
  `enterprise_no` varchar(32) COLLATE utf8_bin NOT NULL COMMENT '工商号',
  `province` varchar(32) COLLATE utf8_bin NOT NULL COMMENT '地址(省)',
  `area` varchar(32) COLLATE utf8_bin NOT NULL COMMENT '地址(区)',
  `city` varchar(32) COLLATE utf8_bin NOT NULL COMMENT '地址(市)',
  `address` varchar(200) COLLATE utf8_bin NOT NULL COMMENT '详细地址',
  `status` varchar(8) COLLATE utf8_bin NOT NULL COMMENT '状态(试用:trial,停用:stop,正式:official)',
  `proposer_Id` bigint(18) DEFAULT NULL COMMENT '申请人Id',
  `enable_flag` varchar(18) CHARACTER SET utf8 NOT NULL COMMENT '是否有效',
  `created_time` datetime NOT NULL COMMENT '创建时间',
  `updated_time` datetime NOT NULL COMMENT '创建时间',
  `expire_time` datetime NOT NULL COMMENT '到期时间 (试用下是默认七天后到期,状态改成停用)',
  `web_site` varchar(100) COLLATE utf8_bin DEFAULT NULL COMMENT '商户门店web站点',
  `sharding_id` bigint(18) NOT NULL COMMENT '分库id',
  `app_web_site` varchar(100) COLLATE utf8_bin DEFAULT NULL COMMENT '商户h5web站点',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='企业账号管理';

实现细节
对于这个功能的CRUD这里就不做赘述,这里主要思考2个问题:
为什么我们要为商家绑定域名?
通过一个图来分析下整个的工作流程
在这里插入图片描述
员工在浏览器中发起ppsk.shop.eehp.cn的访问请求
阿里云域名解析会把ppsk.shop.eehp网址解析到阿里云ECS服务器101.101.108.2
阿里云ECS服务器【101.101.108.2】宿主机会把信息转发到docker-nginx服务器
docker-nginx服务器配置的serverName【*.shop.eehp.cn】转发到gateway服务
gateway服务根据ppsk.shop.eehp.cn兑换企业号100001
根据企业号100001访问目标的商家A
域名和企业号如何建立关联
在security模块的initEnterpriseWeb方法,这里主要有四个方法:
init:初始化企业站点信息到redis,此方法上有==@PostConstruct==注解,表示项目启动时即加载信息
addWebSiteforRedis:添加缓存中的站点,当我们【新增】企业主体信息时调用此方法
deleteWebSiteForRedis:移除缓存中的站点,当我们【删除,仅用】企业主体信息时调用此方法
updateWebSiteforRedis:更新缓存中的站点,当我们修改禁用企业主体信息时调用此方法

/**
 * @ClassName initEnterpriseWebSIteInfo.java
 * @Description 初始化企业站点信息到redis
 */
@Component
public class InitEnterpriseSite {

    @Autowired
    IEnterpriseService enterpriseService;

    @Autowired
    RedissonClient redissonClient;

    /**
     *获得两时间的秒间隔
     */
    public Long secondInterval(Date date1, Date date2) {
        long secondInterval = (date2.getTime() - date1.getTime()) / 1000;
        return secondInterval;
    }

    /***
     * @description 初始化企业站点信息到redis
     */
    @PostConstruct
    public void init(){
        QueryWrapper<Enterprise> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Enterprise::getEnableFlag, SuperConstant.YES)
            .and(wrapper->wrapper
                .eq(Enterprise::getStatus,SuperConstant.TRIAL)
                .or()
                .eq(Enterprise::getStatus,SuperConstant.OFFICIAL));
        List<Enterprise> list = enterpriseService.list(queryWrapper);
        List<EnterpriseVo> enterpriseVos = BeanConv.toBeanList(list, EnterpriseVo.class);
        for (EnterpriseVo enterpriseVo : enterpriseVos) {
            String webSiteKey = SecurityCacheConstant.WEBSITE+enterpriseVo.getWebSite();
            RBucket<EnterpriseVo> webSiteBucket = redissonClient.getBucket(webSiteKey);
            String appWebSiteKey = SecurityCacheConstant.APP_WEBSITE+enterpriseVo.getAppWebSite();
            RBucket<EnterpriseVo> appWebSiteBucket = redissonClient.getBucket(appWebSiteKey);
            Long secondInterval = this.secondInterval(new Date(), enterpriseVo.getExpireTime());
            if (secondInterval.longValue()>0){
                webSiteBucket.set(enterpriseVo,secondInterval, TimeUnit.SECONDS);
                appWebSiteBucket.set(enterpriseVo,secondInterval, TimeUnit.SECONDS);
            }
        }
    }

    /***
     * @description 添加缓存中的站点
     * @param enterpriseVo 企业号
     * @return:
     */
    public void addWebSiteforRedis(EnterpriseVo enterpriseVo){
        String webSiteKey = SecurityCacheConstant.WEBSITE+enterpriseVo.getWebSite();
        RBucket<EnterpriseVo> webSiteBucket = redissonClient.getBucket(webSiteKey);
        String appWebSiteKey = SecurityCacheConstant.APP_WEBSITE+enterpriseVo.getAppWebSite();
        RBucket<EnterpriseVo> appWebSiteBucket = redissonClient.getBucket(appWebSiteKey);
        Long secondInterval = this.secondInterval(new Date(), enterpriseVo.getExpireTime());
        if (secondInterval.longValue()>0){
            webSiteBucket.trySet(enterpriseVo,secondInterval, TimeUnit.SECONDS);
            appWebSiteBucket.trySet(enterpriseVo,secondInterval, TimeUnit.SECONDS);
        }
    }

    /***
     * @description 移除缓存中的站点
     * @param enterpriseVo 企业号
     * @return:
     */
    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值