在介绍SAM系统之前,首先通过几个案例来了解权限系统的概念和设计。
计算机世界中的许多事物都是现实世界的影子。 现实中看到的许多模式/概念都可以在计算机世界中找到。 权限作为现实世界中随处可见的一个概念,当我们谈论私有制和所有权时,经常会提到权限。 权限,在计算机世界中,权限在很多系统中都扮演着重要的角色。 一切皆文件的Linux操作系统是大多数技术人员所熟悉的。 在这样的多用户操作系统中,每个用户都有自己的工作空间,并通过对文件设置权限来管理资源。 你是否还记得游戏素材,QQ里的隐形人对她来说是可见的,生怕她看不到,又下线再上线,却依然被忽视? 你是否还记得,亲密的恋人分手后变成了最熟悉的陌生人,伤心难过? 我的微信、电话、QQ都被拉黑了。 以上都是计算机中使用权限系统的典型案例。 在QQ隐身案例中,你对女神来说是隐身的,这实际上是允许她看到你的隐身状态(真实状态)。 当然,你也给了她你给了别人伤害你的权力; 就恋人而言,恋人已将对方拉入黑名单用户群,让他们看不到对方的动态,成为最熟悉的陌生人; 从此,他们路过你的世界。
RBAC
在上面的例子中,我们可以抽象出这样的模式:“谁对什么(Which)执行How操作”。 比如说恋人的情况,你拉黑对方之后,你(Who)就无法在朋友圈里看到对方(How)的消息(What)。 这是一个经典的RBAC(基于角色的访问控制)权限模型。 RBAC认为权限授权实际上是一个Who、What、How的问题。 在RBAC模型中,Who、What、How构成了访问权限三元组,即“Who(权限的所有者或主体)对What(Which)(访问者所针对的对象或资源)执行How(特定权限)”。许可)。)操作”。
RBAC模型引入了“角色”的概念。 所谓“角色”就是一个或一组用户在系统中可以执行的操作的集合。 它是用户的集合和授权权限的集合。 通过为用户分配角色并为角色授予权限,用户和权限通过角色间接链接起来。 RBAC的基本模型如图所示:
在RBAC中,用户和角色、角色和权限之间存在多对多的关系。 会话是一个用户到多个角色的映射,此时的用户权限可以是激活的角色权限的并集。 RBAC将资源授权管理过程分为两部分。 首先将访问权限与角色关联,然后将角色与用户关联,从而实现用户和访问权限的逻辑分离。
权限系统SAMSAM权限系统模型设计
RBAC模型与直接向用户授予权限的强制访问控制和自由选择访问控制的不同之处在于,权限是分配给角色的。 在 RBAC 中,权限与角色相关联。 用户通过成为适当角色的成员来获得这些角色的权限。 角色可以根据新的需求和系统合并而被授予新的权限,也可以根据需要从角色中获取权限。 回收。 RBAC是一种比传统访问控制更加中立、灵活的访问控制技术。 从零售店员工角色管理的角度来看,创建角色是为了完成各种任务。 根据员工的职责和资历,为员工分配相应的角色。 员工应该能够轻松地从一个角色分配到另一个角色。 角色。 因此,零售业选择实现基于RBAC模型的权限系统来解决商户管理员工角色的问题。
基于RBAC模型思想,SAM权限系统业务模型设计为员工管理和权限管理两部分。 员工管理主要是指对员工进行管理,为员工分配角色。 权限管理主要是指管理菜单、页面、按钮、API等资源。 通过定义最基本的业务功能点作为权限点,实现管理角色对资源主体的请求,形成“用户-角色-权限-资源”的授权模型。
以下是SAM权限系统模型中的一些常用语言:
SAM权限系统模型的实现
在传统的RBAC模型中角色权限设计,通常使用关系表来存储角色和权限集的对应关系,从而将权限和角色关联起来。 可以预见,随着零售业务的不断发展,无数的功能点将会积累,导致相关表中的数据极难维护和使用。 SAM权限系统采用十六进制转换策略解决了这个问题,同时提高了存储效率和权限判定效率。 基本类型为Long的十进制数,也可以看作是由64位0或1组成的二进制。在SAM系统模型设计中,每个功能点被定义为一个权限点,保证全局唯一权限点由idx和pos两个属性组成。 idx表示Long类型空间,pos表示Long类型对应的二进制数中的位置,64位长度可以表示64个不同的功能点。 当64位已满时,就无法再容纳更多的功能点了。 此时idx属性会自动增加,并重新申请一个Long空格。 这样一个64位的Long数,通过0或1的组合,可以表示最多64个不同功能点所持有的权限的状态描述。
例如:权限集合{1}表示具有idx=0,pos=0对应的功能点的权限,权限集合{-1,1}表示具有idx=0,pos∈[0,1,2,。 .,63]idx=1,pos=0对应功能点的权限。
SAM权限系统以二进制方式管理资源和所表示的功能点之间的关系。 它采用计算机二进制的思想,抽象出函数集转换公式,完成资源与二进制文件之间的映射,以及角色与二进制文件之间的映射。 映射。
权限集转换公式:
{(idx0,pos0),(idx0,pos1)…(idxN,posM)} => {Long0,Long1…LongN}
SAM权限系统还通过十六进制思维实现了“谁对什么进行了如何操作”。 当角色请求某个资源(菜单/API)时,它通过权限验证计算公式——十六进制按位“与”运算的运算思路(见下文)判断该角色是否有访问该资源的权限。 通过使用十六进制来实现运算,权限判定的效率将会变得更加高效。 例如,当仓库管理员点击产品库存菜单时,其背后的权限验证计算公式实际上是角色的权限集和资源的权限集的按位与计算。 任何一对序号为idx的Long都不会被计算为0,即两个集合具有共同的功能集合,则认为该角色具有资源的访问权限。
权限验证计算公式:
{Long0,Long1…LongN} & {Long0,Long1…LongM}
SAM权限系统模型的实现遵循RBAC模型的三个原则:最小权限原则、职责分离原则和数据抽象原则。 通过最小权限原则,可以将角色配置为完成任务所需的最小功能集; 职责分离的原则可以通过调用独立且互斥的角色来共同完成敏感任务来体现,比如要求仓库经理和产品经理共同参与一个产品。 数据抽象可以通过权限的抽象来体现,比如仓库操作、商品配送、库存管理等抽象权限,而不是操作系统提供的典型的读、写、执行权限。
SAM权限系统架构
零售业通过PC、App、Pad满足不同商户的终端需求。 因此,SAM权限系统需要满足零售中不同的客户端权限业务场景,同时还必须支持微商城产品权限业务。 SAM权限系统采用微服务对外提供服务,采用分布式分层架构实现。 它主要由两部分组成:客户端和服务器端。 客户端以轻量级的方式嵌入到业务系统中,提供对不同业务系统的角色访问。 资源控制; 服务端通过提供Dubbo服务和Nova服务与客户端交互。 服务器主要管理员工、菜单、角色、API、功能点等数据。 SAM作为基础服务角色权限设计,每天都会有海量的请求。 Redis缓存用于解决性能问题。 选择Druid作为数据库连接池,管理数据库连接和释放。 同时可以通过与天网监控平台对接观察系统运行状态,提高系统的稳定性。
有赞零售系统基于SAM实现的资源的角色访问控制主要是API验证和菜单渲染。 任何零售店铺登录有赞零售系统后,点击某个菜单或页面元素(按钮、链接……),都会进行菜单渲染和API接口验证。 由于两部分调用量巨大,且不同客户端的请求量不同,为了防止相互干扰,菜单渲染、API验证等能力都在不同客户端实现。
菜单渲染
通过客户端访问SAM,在客户端进行菜单渲染。 目前,SAM已经提供了php/node js两套客户端,供web层访问和渲染。
菜单渲染的过程可以分为三点:
1. 节点定位
根据系统功能的划分,菜单通常以树的形式显示。 以零售PC后端为例,页面上显示的所有元素都被视为菜单。 此类菜单元素包括:菜单、页面和按钮。 在后台访问时,用户停留的菜单通常是一个页面。 页面有一个全局唯一的属性:URL。 向上:可以通过父菜单找到根节点。 往下,页面可能包含一些子菜单——按钮。 因此,SAM只需根据当前请求的URL定位到后台菜单树中唯一的页面菜单,同时获取该菜单的节点路径和按钮即可。
2. 权限计算
我们已经获得了用户的角色权限和完整的菜单树。 根据每个菜单节点的权限集,我们可以计算出当前用户对该节点的访问权限。 根据计算结果,客户端可以呈现不同的菜单。 例如,当用户通过拼写URL访问未经授权的页面时,会提示该页面非法。 未经授权访问的菜单和按钮将自动变灰且无法点击。
3、属性转移
默认菜单没有 URL 属性。 菜单的URL属性是通过传递子菜单的URL来生成的。 SAM会选择第一个授权的子菜单的URL作为父节点的属性,并逐级传递给一级菜单。
API权限验证
除了菜单之外,API 是零售系统中请求的另一种资源。 API验证是除了菜单渲染之外的权限控制的又一保障。 当API请求通过Carmen(API网关)转发到具体业务系统时,业务系统内嵌的SAM API验证客户端首先会通过上述权限验证计算公式判断该角色是否有访问该API的权限。 如果权限验证通过,则执行后续业务逻辑。具体流程如下图所示
API权限验证的伪代码实现:
#权限不通过错误码提示信息
AUTHPERM_ERROR(231000401,"您没有权限执行该操作!")
# 织入点
@Before("@annotation(com.youzan.sam.common.Auth)")
# 切面处理方法
def handle(JoinPoint pjp):
# 可以启动时或者运行时控制该开关是否对API进行权限校验
if(!enable):
return
# 权限校验结果包装对象
def pass=checkPermission()
# 权限校验执行成功
if (pass.isSuccess()):
# 权限校验通过
if(pass.getData().get("isSuccess")):
return
# 权限校验不通过
else:
throw new BusinessException(AUTHPERM_ERROR.getCode,AUTHPERM_ERROR.getMessage());
# 权限校验执行失败
else:
throw BusinessException(pass.getCode(), pass.getMessage())
# 权限校验方法
def checkPermission():
# 判断是否需要走权限校验,对于某些内部调用可以直接跳过
{...}
# 获取卡门(API网关)隐式参数,运用了dubbo的隐式传参的能力
def kdt_id=RpcContext.getContext().getAttachment(Constants.KDT_ID_KEY)
def admin_id=RpcContext.getContext().getAttachment(Constants.ADMIN_ID_KEY)
def service = RpcContext.getContext().getAttachment(Constants.SERVICE_KEY)
def method = RpcContext.getContext().getAttachment(Constants.METHOD_KEY)
def version = RpcContext.getContext().getAttachment(Constants.VERSION_KEY)
# 上述参数的校验
{...}
# 通过StaffPermServiceProxy获取角色的权限集
def staffPerm=StaffPermServiceProxy.getStaffPerms(adminId, kdtId)
# 通过APIPermServiceProxy获取API的权限集
def apiPerm=APIPermServiceProxy.getServicePerms(service, version, method)
# 运用权限校验计算公式判定该角色是否可以访问此API
{...}
# 返回结果
return pass
API权限验证流程可以总结如下:
1、业务方在对应需要权限验证的API上标注@Auth注解。 Spring框架在初始化业务bean时,会扫描该bean是否有@Auth注解的注解方法。 对于带有@Auth注解的,它会创建一个代理类,然后将权限方面编织到代理类中;
2、当业务调用@Auth注解标记的方法时,会执行权限验证切面逻辑。 首先,检查权限验证开关,判断是否需要权限验证。 该开关可以在运行时动态设置;
3. 如果需要,调用AuthService的权限验证方法。 AuthService会根据店铺ID和用户ID从SAM服务器获取员工角色权限信息,并根据Carmen(API网关)隐含参数中的服务、方法、版本去到SAM服务。 客户端获取对应的API权限(相比直接在对应的API上标记权限点,这种方式更加灵活,可以方便地随着业务API版本的升级而升级。同时结合Carmen(API网关),API可分流,不同商户可对应不同的API权限验证);
4、获取角色权限集和API权限集后,根据上述角色和权限验证逻辑进行权限验证。 如果验证通过,则正式发起API请求。 如果验证失败,会提示没有权限。
SAM权限系统抽象模型
产品分析完需求后,将需求交给开发完成。 SAM权限系统不仅支持零售业务,还支持微商城业务。 每个零售模块都有不同的产品支持,以便更好地满足服务商户的需求并方便对产品的分析。 SAM权限系统可以抽象为以下模型。 商家和产品可以从不同的角度接入SAM权限系统。 例如,如下图所示,想要担任运营角色的商户需要具备创建新产品和查看订单的能力,还需要一个只能查看订单的收银员。 从产品本身的设计角度来分析。 对应的模块是产品管理和订单管理。 相应的模块下有相应的产品和订单菜单。 最后,角色权限反映在页面元素和 API 中,例如用于创建新产品的按钮。 并且查看顺序的按钮会显示不同的渲染风格; 按钮触发对应不同的与后端交互的API,不同的角色有不同的API执行能力。
期待自定义角色
在了解商家的需求后,Retail提供了8种默认角色来支持单店版本的员工角色问题。 零售业务复杂,默认字符往往无法应对所有场景。 现在一些定制字符已经在一些零售店使用。 未来各商户将全面支持自定义角色,任意角色可自定义任意权限。
多重角色
为了降低劳动力成本,一些零售商经常让一名员工担任多个角色,因此需要为一名员工提供担任多个角色的能力。 零售业务已经在使用多角色功能。
零售中台支持
零售中台是有赞零售的旗舰产品。 旨在为商户提供涵盖线上、多渠道、线下门店的全渠道解决方案,用数字化运营思路帮助商户吸引新客、增加重复购买。 。 其业务形态非常复杂,涉及多种角色和权限的组合,每个商户可能都有一些个性化的需求。 如何提供灵活的适配能力是SAM系统面临的挑战。
定制菜单
过去,后端功能的发布和上线往往是由发布系统控制的。 发布后地图场景,该功能会立即上线,如果发现故障,会立即回滚。 通过菜单管理,SAM可以在线实时控制任意菜单、页面和按钮的渲染状态,并实现页面和功能的平滑上线和离线。
技术改造
SAM作为零售等业务的通用基础组件,需要构建成高可用、高性能、易扩展、可扩展且安全的系统。 随着业务的不断接入,通过系统的不断改造来支撑业务的持续发展。
结论
该权限系统目前属于有赞零售技术团队,对外开放权限访问和员工服务能力。 目前团队业务发展迅速,HC持续开放。 我们期待更多有志之士加入我们,共创美好未来。 (内部推荐电子邮件:,)