MarkLogic用户更新权限校验代码优化方案咨询
MarkLogic权限校验逻辑优化方案
针对你需要校验当前用户是否持有任意更新权限的需求,有多个更稳定、性能更优的实现方式,首先先指出你现有代码的问题:
现有代码的逻辑存在2个明显缺陷:
- admin权限判断写法错误:
$user-roles eq xdmp:role("admin")中的xdmp:get-current-roles()返回的是角色ID序列,当用户同时持有多个角色时,该等值判断永远不成立- 手动匹配权限的逻辑没有兼容MarkLogic的角色继承规则,若用户持有的角色继承了具备更新权限的其他角色,手动匹配逻辑会漏掉该场景导致判断错误
推荐优化方案(优先使用MarkLogic原生安全API)
MarkLogic自带了经过性能优化、逻辑完备的安全校验函数,不需要手动拉取权限匹配,同时自动兼容角色继承、admin默认权限规则,还会抛出标准的SEC-PERMDENIED错误方便日志排查:
(: 直接校验当前用户对指定$uri是否持有insert或update权限,校验失败自动抛出标准权限不足错误 :) xdmp:security-assert($uri, ('insert', 'update')) (: 校验通过后执行业务逻辑即可 :) if ($value) then (: 返回你的XML节点 :) else xdmp:document-insert($uri, $your-content, $optional-custom-permissions)
如果你不需要针对特定文档校验,只是要判断当前用户有没有全局的文档更新权限,可以直接用权限断言:
xdmp:security-assert("http://marklogic.com/xdmp/privileges/xdmp-document-update", "execute")
保留自定义权限逻辑的优化方案
如果你的perm:get-permissions返回的是业务自定义权限,不是MarkLogic原生文档权限,可按以下方式修正逻辑:
let $permissions := perm:get-permissions($uri) let $is-authorized := exists($permissions[ sec:capability = ('insert', 'update') and sec:role-id = xdmp:get-current-roles() ]) or xdmp:has-role("admin") return if ($is-authorized) then if ($value) then (: 返回你的XML节点 :) else xdmp:document-insert($uri, $your-content) else fn:error(QName("", "CUSTOM-PERM-DENIED"), "当前用户无更新权限")
额外优化建议
- 无特殊需求不要跳过MarkLogic原生权限校验:
xdmp:document-insert执行时默认就会校验当前用户对目标URI的更新权限,不需要额外提前做权限校验 - 权限判断尽量走原生API:原生API调用的是MarkLogic内置的安全缓存,比你自定义查询权限的逻辑性能高1~2个数量级,且不会出现逻辑漏洞
内容的提问来源于stack exchange,提问作者ravvi
相关产品推荐
相关产品推荐

