ALFA中1:n关系与复杂属性类型的可行性及规则实现问询
ALFA对字符串列表/复杂类型列表属性的支持及规则编写
没问题,ALFA完全支持你提到的这两类1:n关系属性,不过有个关键细节要注意:XACML(以及其抽象语言ALFA)里用来表示集合类型的是bag而非list,所以咱们先调整属性定义,再给你写对应的授权规则示例。
1. 基于字符串列表的1:n关系
首先修正你的属性定义,把list<string>替换为bag[string](这是XACML标准的集合类型):
namespace com.mycompany { namespace resources { namespace patient { attribute trustedDoctorIds{ category = resourceCat id = "trustedDoctorIds" type = bag[string] } } } }
假设你要实现的需求是只有当医生的ID出现在患者的trustedDoctorIds集合中时,允许医生查看患者资源,对应的ALFA规则可以这么写:
rule allowTrustedDoctorViewPatient { target clause resourceType == "patient" and actionId == "view" // stringOneAndOnly确保取出主体的唯一ID(假设请求中subject.id是单值) condition stringIsIn(stringOneAndOnly(subject.id), resource.trustedDoctorIds) permit }
这里用到的stringIsIn函数是XACML内置的,专门用来判断单个字符串是否存在于字符串集合中。
2. 基于复杂类型列表的1:n关系
同样,先把list<doctor>改成bag[doctor],另外需要显式定义doctor这个复杂类型(ALFA需要明确的类型声明):
namespace com.mycompany { // 先定义doctor复杂类型,包含id和lastname字段 type doctor { id: string, lastname: string } namespace resources { namespace patient { attribute trustedDoctors{ category = resourceCat id = "trustedDoctors" type = bag[doctor] } } } namespace subjects { namespace doctor { attribute id { category = subjectCat id = "id" type = string } attribute lastname { category = subjectCat id = "lastname" type = string } } } }
如果需求是当前医生的ID匹配trustedDoctors集合中任意一个医生对象的id字段时,允许访问,对应的规则可以用anyOf函数来遍历集合做匹配:
rule allowTrustedComplexDoctorAccess { target clause resourceType == "patient" and actionId == "view" // anyOf遍历trustedDoctors集合,检查是否有医生的id和当前主体id一致 condition anyOf(resource.trustedDoctors, doctor => doctor.id == stringOneAndOnly(subject.doctor.id)) permit }
anyOf函数会对集合中的每个元素执行lambda表达式,只要有一个元素满足条件,整个条件就返回true。
内容的提问来源于stack exchange,提问作者OneWorld
相关产品推荐
相关产品推荐

