Text|毛承光、马春杰谈零售有赞作为商家服务公司,通过产品和服务帮助互联网时代的商家取得成功。在新零售浪潮下,有赞零售为商家提供不同规模的门店和网店管理解决方案,助力零售商快速进入新零售时代。与传统的网上商城场景不同,零售业面临着全新的商业场景和问题。一家运营良好的新零售门店,通常需要包括老板、店长、客服、收银、核销、仓管、财务等十余名员工,不同能力的角色分工搭配。零售商面临的一大挑战是如何优雅地管理每一位员工,自由分配角色,轻松顺利地解决员工角色管理问题。在充分分析零售行业的业务场景,不断探索和探讨员工角色管理方案后,权限系统SAM(SecurityAccessManager)应运而生。SAM是有赞零售在员工角色权限管理道路上探索的里程碑,支持零售PC、App和Pad产品授权业务,任何使用有赞零售的零售门店都可以通过有赞零售提供的服务,灵活地为门店员工分配角色。SAM授权体系,责任到人,提升门店运营效率;在支持零售业务的同时,抽象出一套权限管理框架,以同样的方式支持其他业务线产品(微商城)。在介绍SAM系统之前,先通过几个案例来了解一下权限系统的概念和设计。计算机世界中的很多事物都是现实世界的影子,很多在现实中看到的模式/概念都可以在计算机世界中找到。你有没有想过,你在QQ里可以看到她隐形,生怕她看不到,下线再上线,你还是被忽略;于,微信,电话,QQ被封。这些案例都是计算机权限系统对现实世界的反映。当你对女神来说是隐形的时候,你实际上是给了她看到你隐形状态(realstate)的权限。当然,你也给了别人伤害你的权利。权限;恋人拉入黑名单用户群,看不到对方动态,成为最熟悉的陌生人;从此,路过你的整个世界。在上面的RBAC例子中,我们可以抽象出这样一个模式:“WhoperformsHowoperationsonWhat(Which)”。比如恋人,你拉黑对方后,你(Who)就不会在朋友圈看到(How)对方的消息(What)。这是一个经典的RBAC(Role-BasedAccessControl)权限模型。RBAC认为授权实际上是一个Who,What,andHow的问题。在RBAC模型中,Who、What、How构成访问权限的三元组,即“Who(权限的拥有者或主体)对What(对象或资源)执行How(特定权限)当局))操作”。RBAC模型引入了“角色”的概念。所谓“角色”就是一个或一组用户在系统中所能执行的操作的集合。它是用户的集合,也是授权权限的集合。通过给用户分配角色,给角色授予权限,用户和权限通过角色间接联系起来。RBAC的基本模型如图所示:在RBAC中,用户与角色、角色与权限之间是多对多的关系。会话是一个用户到多个角色的映射,此时的用户权限可以是激活的角色权限的并集。RBAC将资源授权管理过程分为两部分。首先将访问权限与角色关联起来,再将角色与用户关联起来,从而实现用户与访问权限的逻辑分离。权限系统SAMSAM权限系统模型设计RBAC模型不同于强制访问控制和自由选择访问控制直接授予用户权限,它是将权限授予角色。在RBAC中,权限与角色相关联,用户通过成为相应角色的成员来获得这些角色的权限。可以根据新的需求和系统集成赋予角色新的权限,也可以根据需要从角色中获取权限。回收。RBAC是一种比传统访问控制更加中立和灵活的访问控制技术。从零售店员工角色管理的角度来看,创建角色是为了完成各种任务,并根据员工的职责和资格分配相应的角色。员工应该很容易地从一个角色分配到另一个角色。因此,该零售商选择基于RBAC模型实现权限体系,解决商户管理员工角色的问题。根据RBAC模型的思想,SAM权限系统的业务模型设计为员工管理和权限管理两部分。员工管理主要是指对员工进行管理,为员工分配角色。以基础业务功能点为权限点,实现管理角色对资源主体的请求,构成“用户-角色-权限-资源”的授权模型。下面介绍一些SAM权限系统模型中常用的语言:Employee:角色的载体,权限的执行者Role:角色是权限集的进一步映射。业务系统可以动态管理角色。为了方便用户,每个业务可以提供一个默认的角色列表,以满足不同的员工权限。权限点:全局唯一的状态,用来表示某个功能点对应的权限功能点:逻辑定义用来描述系统资源的最小基本单位。每个功能点对应一个唯一的权限点功能集(permissionset):即功能点的集合。一组功能点按照特定的格式组合在一起。API:请求系统资源的通道和Action,带功能设置属性menu:组织系统资源并展示给请求者的入口,带功能设置属性page:视为特殊菜单,带URL属性button:更精细-页面中细粒度的资源入口,用作特殊菜单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权限系统也实现了“谁执行了Howon”的思想WhatOperation”,当一个角色请求某个资源(menu/API)时,可以通过权限校验计算公式判断该角色是否有访问该资源的权限——二元“AND”运算运算的思想(见下图)使用base实现操作,权限判断的效率会变得更加高效,比如仓库管理员点击商品库存菜单时,其背后的权限验证计算公式其实就是按位AND计算角色的权限集和资源的权限集,任意一对序号为idx的Long不计算为0,即这两个集合有共同的功能集,认为角色可以访问resources.权限验证计算公式:{Long0,Long1...LongN}&{Long0,Long1...LongM}SAM权限体系模型的实现遵循最小权限原则、责任分离原则和数据抽象原则三个原则在RBAC模型中。原则可以将角色配置为完成任务所需的最小功能集;以职责分离原则,可以体现为调用相互独立和相互排斥的角色共同完成敏感任务,比如要求仓库管理员和商品管理员共同参与一个产品。数据抽象可以体现在权限的抽象上,比如仓库管理、商品发货、库存管理等抽象权限,而不是典型的操作系统提供的读、写、执行权限。SAM权限系统架构Retail使用PC、App、Pad来满足不同商户的终端需求。因此,SAM权限系统需要满足不同零售客户端权限的业务场景,同时支持微商城产品权限业务。SAM权限系统以微服务的形式对外提供服务,采用分布式分层架构实现。它主要包括客户端和服务器两部分。客户端以轻量级的方式嵌入到业务系统中,提供给不同的业务系统实现角色访问。资源控制;服务端通过提供Dubbo服务和Nova服务与客户端进行交互。服务器主要对员工、菜单、角色、API、功能点进行数据管理。SAM作为一项基础服务,每天都有海量的请求。Redis缓存用于解决性能问题。选用Druid作为数据库连接池,管理数据库的连接和释放。同时通过与天网监控平台对接,观察系统运行状态,提高系统稳定性。基于SAM的有赞零售系统主要通过API校验和菜单渲染实现对资源的角色访问控制。任何零售店登录有赞零售系统后,点击页面上的某个菜单或页面元素(按钮、链接……),都会进行菜单渲染和API接口验证。由于两部分调用量巨大,且不同客户端请求量不同,为防止相互干扰,菜单渲染、API校验等能力在不同客户端实现。菜单渲染SAM通过客户端访问,菜单渲染在客户端进行。目前SAM已经提供了两套客户端,php/nodejs,供web层访问和渲染。菜单渲染的过程可以分为三点:1.节点定位根据系统功能的划分,菜单通常以树的形式展示。以零售PC后台为例,页面上显示的所有元素都被认为是一种菜单。此类菜单元素包括:菜单、页面和按钮。后台访问时,用户停留的菜单通常是一个页面,页面有一个全局唯一的属性:URL,up:可以通过父菜单找到根节点,down,页面可能包含一些子菜单-纽扣。因此,SAM只需要根据当前请求的URL在后台菜单树中定位唯一的页面菜单,同时获取菜单的节点路径和按钮即可。2.权限计算我们已经获取了用户的角??色权限和完整的菜单树。根据每个菜单节点的权限集,可以计算出当前用户对该节点的访问权限。根据计算结果,客户端可以呈现不同的菜单。例如,当用户通过拼写URL访问未经授权的页面时,会提示非法,未经授权访问的菜单和按钮会自动变灰,无法点击。3.属性传递默认菜单没有URL属性。菜单的URL属性是通过传递子菜单的URL生成的。SAM会选择第一个授权的子菜单的URL作为父节点的属性,逐级传递给一级菜单。API权限验证除了零售系统中的菜单,API是请求的另一种资源类型。API校验是菜单渲染之外的又一种权限控制保障。当通过Kamen(API网关)的API请求被转发到具体的业务系统时,业务系统中嵌入的SAMAPI验证客户端会先通过上述权限验证计算公式判断该角色是否有访问API的权限,如果是权限验证通过,会执行下面的业务逻辑。具体过程如下图API权限验证的伪代码实现:#Permissionnotpassed错误码提示信息AUTHPERM_ERROR(231000401,"您没有执行该操作的权限!")#织点@Before("@annotation(com.youzan.sam.common.Auth)")#分段处理方法defhandle(JoinPointpjp):#可以控制开关是否在启动时或运行时对API进行权限验证if(!enable):return#权限验证结果包装对象defpass=checkPermission()#权限验证执行成功if(pass.isSuccess()):#权限验证通过if(pass.getData().get("isSuccess")):return#权限验证failedPasselse:thrownewBusinessException(AUTHPERM_ERROR.getCode,AUTHPERM_ERROR.getMessage());#权限验证失败else:throwBusinessException(pass.getCode(),pass.getMessage())#权限验证方法defcheckPermission():#判断是否需要权限验证,部分内部调用直接跳过{...}#获取Kamen(API网关)的隐式参数,利用dubbo隐式传参的能力defkdt_id=RpcContext.getContext().getAttachment(Constants.KDT_ID_KEY)defadmin_id=RpcContext.getContext().getAttachment(Constants.ADMIN_ID_KEY)defservice=RpcContext.getContext().getAttachment(Constants.SERVICE_KEY)defmethod=RpcContext.getContext().getAttachment(Constants.METHOD_KEY)defversion=RpcContext.getContext().getAttachment(Constants.VERSION_KEY)#对以上参数的校验{...}#通过StaffPermServiceProxy获取角色的权限集defstaffPerm=StaffPermServiceProxy.getStaffPerms(adminId,kdtId)#通过APIPermServiceProxy获取API的权限集defapiPerm=APIPermServiceProxy.getServicePerms(service,version,method)#使用权限验证计算公式判断角色是否可以访问这个API{...}#returnresultreturnpassAPI权限验证过程可以概括为:业务方在对应需要权限验证的API上标注@Auth注解,Spring框架在初始化和创建时扫描bean是否有@Auth注解注解方法业务bean。如果标注了@Auth注解,则会创建一个代理类,然后将权限切面编织到代理类中;当业务调用@Auth注解标记的方法时,会执行权限验证切面逻辑,首先会检查权限验证开关,判断是否需要权限验证,开关可以在运行时动态设置;必要时调用AuthService的权限验证方法,AuthService会根据店铺ID和用户ID,根据Kamen(API网关隐含参数)、service、method、version从SAM服务器获取员工角色权限信息去SAM服务器获取对应的API权限(相比直接在对应的API上标记权限点,这种方式更加灵活,可以随着业务API版本的升级而升级。升级非常方便,并结合Kamen(API网关)可以对API进行导流,不同的商户可以对应不同API的权限校验,获取到角色权限集和API权限集后,根据上述角色和权限校验逻辑进行权限校验。验证通过后,将正式发起API请求。如果验证失败,会提示没有权限。SAM权限系统抽象模型产品需求分析后,将需求交给开发完成。SAM权限系统在支持零售业务的同时,也支持微商城业务。每个零售模块由不同的产品支持,以更好地满足服务商户的需求,方便对产品进行分析。SAM权限体系可以抽象为如下模型。商家和产品可以从不同的角度接入SAM权限系统。比如如下图,一个想要运营角色的商户,需要有新建商品和查看订单的能力,同时需要一个只有查看订单能力的收银员。从产品本身的设计角度来分析产品。对应的模块是产品管理和订单管理。在相应的模块下,有相应的产品和订单菜单。最后,角色权限体现在页面元素和API中,例如创建新产品的按钮。而查看订单的按钮会有不同的渲染风格;按钮触发器对应于与后端交互的不同API,不同的角色具有不同的API执行能力。未来展望自定义角色在了解商家需求后,零售提供了8个默认角色来支持单店版员工角色。零售业务复杂,默认角色往往不适合所有场景。现在一些零售商店已经使用了一些自定义字符。未来自定义角色将支持所有商户,自定义任意权限的任意角色。多重角色为了降低人力成本,一些零售商往往要求一名员工担任多个角色,因此有必要为一名员工提供扮演多个角色的能力。零售业务已经在使用多角色功能。零售平台的支持零售平台是有赞零售的旗舰产品,旨在为商家提供涵盖线上、多渠道、线下门店的全渠道解决方案,用数据化的运营思路帮助商家吸引新顾客。客户并增加回购。它的业务形态非常复杂,涉及多种角色和权限的组合,每个商户都可能有一些个性化的需求。如何提供灵活的适配能力是对SAM系统的挑战。以往自定义菜单后台功能的发布和上线往往由发布系统控制。发布后,功能立即上线,一旦发现故障,立即回滚。通过菜单管理,SAM可以实时在线控制任意菜单、页面、按钮的渲染状态,轻松实现页面和功能的注销和退出。技术转型SAM作为零售等业务的公共基础设施组件,需要构建成高可用、高性能、易扩展、可伸缩、安全的系统。随着业务的不断接入,业务的不断发展离不开系统的不断改造。结论权限系统目前属于有赞零售技术团队,对外开放权限接入和员工服务能力。目前,团队业务发展迅速,慧聪持续开放。我们期待更多的有志之士加入我们一起做事。
