一个中型电商网站的后台,运营要改商品价格,客服要处理退款,财务要导出报表。这三个人用的是同一套后台系统,但你能保证客服不会点进财务的页面吗?
很多公司的做法是给所有人分配超级管理员账号。这等于把所有门禁卡发给了每个人——出了事根本查不到是谁干的。RBAC(基于角色的访问控制)就是解决这个问题的。
一、先定角色,再定权限
RBAC的核心思路很简单:不直接给用户分配权限,而是给角色分配权限,用户关联角色。一个用户可以属于多个角色,一个角色可以拥有多个权限。
实际落地时,角色定义要贴合业务场景。比如电商后台可以定义这几类角色:运营专员(商品增删改、活动配置)、客服专员(订单查看、退款处理、用户沟通)、财务专员(报表导出、资金对账)、系统管理员(用户管理、权限分配、系统配置)。
权限粒度建议分三层:页面级(能不能看到这个菜单)、操作级(能不能点这个按钮)、数据级(只能看自己部门的数据还是全部数据)。三层缺一不可,只有页面级管控等于形同虚设。
二、数据权限是真正的分水岭
页面权限和操作权限相对好做,难点在数据权限。同样是查看订单页面,运营能看到全量订单,客服只能看到售后工单关联的订单,这就需要数据级过滤。
推荐的做法是在数据查询层加权限拦截。比如通过MyBatis的拦截器或Hibernate的Filter,根据当前用户的角色自动拼接SQL条件。业务代码不需要感知权限逻辑,减少遗漏。
判断数据权限设计是否合格,有个简单标准:如果一个普通客服用接口测试工具直接调用订单查询接口,他能不能拿到超出权限的数据?如果能,说明后端校验有漏洞。
三、权限校验必须后端兜底
前端隐藏菜单和按钮只是体验优化,不是安全措施。攻击者直接调用API就能绕过前端控制。所以每个后端接口都必须做权限校验,不依赖前端传参。
具体实现上,可以用注解方式标注接口所需权限,比如@RequiresPermission("order:export"),在拦截器里统一校验。这样即使新增接口忘记加注解,默认拒绝访问也比默认放行安全。
另外,权限变更后要立即生效。有些系统把权限缓存在本地,管理员撤销了某用户的权限,但缓存没刷新,该用户还能操作半小时。设置合理的缓存过期时间,或者在权限变更时主动清除缓存。
RBAC不是什么高深的技术,但真正落地好的不多。角色定义清晰、数据权限到位、后端校验兜底,做到这三点,后台安全等级直接上一个大台阶。