Pact开发报require-capability未授权错误如何授予模块PRIVATE capability?
报错原因
require-capability 不会自动授予权限,仅会校验当前执行作用域内,是否已经通过with-capability完成了对应capability的授权。你直接调用increase-count时,上下文从未授予过PRIVATE权限,因此触发报错。
另外你当前写的(defcap PRIVATE () true)存在安全缺陷:capability体直接返回true,意味着任意外部代码都可以自行通过with-capability拿到PRIVATE权限,完全达不到「仅模块内部可调用」的控制效果。
正确实现方案
要实现仅模块内部代码可调用increase-count的效果,需要从两个维度修正:
- 给
PRIVATE能力加模块治理权限约束,禁止外部主体直接获取该权限 - 所有模块内部调用
increase-count的逻辑,通过with-capability在作用域内临时授予PRIVATE权限,出作用域后权限自动回收
修正后的参考代码
;; 定义模块治理用的keyset,部署时绑定对应管控密钥即可 (define-keyset 'free.guard-test-01.module-owner-keyset (read-keyset "module-owner")) (module free.guard-test-01 GOVERNANCE ;; 模块治理权限控制 (defcap GOVERNANCE () (enforce-keyset 'free.guard-test-01.module-owner-keyset) ) (defcap PRIVATE () "模块内部私有调用权限" ;; 核心约束:仅持有模块治理权限的上下文可授予PRIVATE权限,外部用户无法直接获取 (require-capability (GOVERNANCE)) ) (defschema count-schema count:integer ) (deftable counts-table:{count-schema}) (defun get-count (key:string) (with-default-read counts-table key { "count": 0 } (at "count") ) ) (defun increase-count (key:string) ;increase the count of a key in a table by 1 (require-capability (PRIVATE)) (update counts-table key {"count": (+ 1 (get-count key))}) ) ;; 对外暴露的合法调用入口,模块内部逻辑可合法获取PRIVATE权限 (defun public-increment (key:string) (with-capability (PRIVATE) (increase-count key) ) ) )
关键注意事项
- 禁止将需要做内部访问控制的capability体直接写为
true,否则权限控制完全不生效 require-capability只做权限存在性校验,所有需要权限的代码逻辑,必须包裹在对应权限的with-capability作用域内才能正常执行- 如果需要从其他模块内部函数调用
increase-count,只要调用路径最终是从模块管控的合法入口发起、在with-capability (PRIVATE)的作用域内即可正常执行,外部无授权的调用会直接被拦截
内容的提问来源于stack exchange,提问作者Nexion21
相关产品推荐
相关产品推荐

