权限冲突本质是同一资源被多个规则同时作用,需显式定义优先级;常见于SSH/Git多账号路由错配、RBAC权限合并逻辑缺陷、前端Token存储未隔离四层面协同问题。
权限冲突的本质是“同一资源,多个规则同时生效”
当一个用户属于多个角色、拥有多个身份源(如部门组+项目组+临时权限),而这些来源对同一资源(比如数据库表 orders 或 git 仓库 git@github.com:org/internal.git)给出不同甚至相反的权限时,系统必须决定“听谁的”。这不是 bug,而是设计必然——关键在于你是否显式定义了优先级和匹配顺序。
常见错误现象包括:明明给 A 用户加了 write 权限,却仍报 Permission denied;或用户能删生产数据,但审计日志显示其所属角色只应有 read 权限。这类问题往往不是权限没配,而是多条规则打架后,低优先级规则“赢了”。
SSH 和 HTTPS 多账号场景下,权限冲突实际是路由错配
Git 多账号不是权限模型冲突,而是客户端根本没把请求发给正确的“身份入口”。比如你配置了两个 GitHub 账号,但 ~/.ssh/config 没写对 Host 别名,或 Git remote URL 仍用默认的 github.com,OpenSSH 就会坚持用 ~/.ssh/id_rsa 这把默认钥匙去敲门——哪怕你本地有 id_ed25519_work 和 id_ed25519_personal 两把钥匙,它也视而不见。
- 确保每个 remote URL 使用自定义 Host 名(如
git@gh-work:user/repo.git),而非原始域名 -
~/.ssh/config中每个Host块必须有唯一且匹配的HostName github.com和IdentityFile - HTTPS 场景下,别依赖浏览器自动填密码;改用
git credential.helper store+ 不同https://work-token@github.com和https://personal-token@github.comURL 显式区分
RBAC 系统中,权限合并必须禁用“覆盖式赋权”,启用“最小交集+显式拒绝”
很多权限框架(如 Django Guardian、Casbin、阿里云 RAM)默认把多个角色的权限做“并集”,看似方便,实则埋雷:用户 A 同时属“财务组”(可读 salary 表)和“实习生组”(被显式拒绝写 salary),若系统只做并集,就可能忽略拒绝规则,导致越权写入。
- 检查你用的权限库是否支持
deny规则优先于allow(例如 Casbin 的deny-override模型) - 避免在角色中混用“允许全部字段”和“禁止某字段”,应拆成细粒度权限项,如
salary:read:base和salary:read:bonus - 在用户激活会话时,强制执行一次权限归一化计算,而不是运行时动态查多张权限表再拼结果
Vue/React 前端 Token 冲突,本质是 localStorage 键名没隔离
前端没“多账号”概念,只有“当前页面存了哪个 Token”。当你在同一个域名下用 localStorage.setItem('token', ...) 存两个账号的凭证,后存的必然覆盖前存的——这不是权限冲突,是存储逻辑缺陷。
- 不要用固定键名;改为
localStorage.setItem(`token_${accountId}`, token),并在请求拦截器中根据当前上下文选对应键 - 避免用
sessionStorage以为它能隔离标签页——Chrome 中同一站点的多个 tab 共享一个sessionStorage实例(除非开无痕窗口) - 如果使用 Cookie,必须为每个账号设置不同
Path(如/app/work/vs/app/personal/)或不同子域(work.example.comvspersonal.example.com)
localStorage 键,就能让所有策略失效。










