XACML3策略疑问:不满足Condition为何返回Not Applicable而非Deny
这是个非常典型的XACML逻辑误解问题,咱们一步步拆解清楚:
核心原因:XACML Rule的评估逻辑
首先要明确XACML中单个Rule的决策规则:
- 当Rule的Target不匹配时,Rule返回
NotApplicable; - 当Rule的Target匹配时,才会评估Condition(如果存在):
- 如果Condition计算为
True→ Rule返回其配置的Effect(你的案例里是Permit); - 如果Condition计算为
False→ 这个Rule不会触发任何允许/拒绝的决策,直接返回NotApplicable。
- 如果Condition计算为
简单说:你的Permit Rule只有在Condition满足时才会输出Permit,不满足时它就相当于“不存在”(NotApplicable),而不是输出Deny。
结合你的Policy分析
你的Policy配置:
- Policy的Target匹配了请求中的
resource-id=MyApp,所以这个Policy会被纳入评估; - Policy里只有一个Rule:
Effect="Permit",且带Condition; - 当请求的
age≠age2时,Condition为False,这个Rule返回NotApplicable; - 你的Policy使用的Rule组合算法是
deny-overrides,这个算法的逻辑是:- 如果有任何Rule返回
Deny,直接返回Deny; - 否则,如果有任何Rule返回
Permit,返回Permit; - 如果所有Rule都返回
NotApplicable,则整个Policy返回NotApplicable。
- 如果有任何Rule返回
因为你的Policy里没有任何Rule返回Deny,所以当唯一的Permit Rule不生效时,整个Policy就返回NotApplicable。
如何实现“不满足Condition则返回Deny”?
如果你希望当Condition不满足时返回Deny,有两种常用方案:
方案1:添加一个默认Deny的Rule
在你的Permit Rule之后添加一个不带Condition的Deny Rule,这样当Permit Rule不生效时,这个Deny Rule会触发:
<Rule Effect="Deny" RuleId="default-deny-rule"> <Target /> <!-- 空Target意味着匹配所有请求 --> </Rule>
结合deny-overrides算法,只要这个Deny Rule的Target匹配(这里总是匹配),就会返回Deny,覆盖NotApplicable的结果。
方案2:使用deny-unless-permit组合算法
把Policy的RuleCombiningAlgId改成urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-unless-permit,同时添加上述默认Deny Rule。这个算法的逻辑是:
- 只要有一个Rule返回
Permit,就返回Permit; - 否则,如果有任何Rule返回
Deny,返回Deny; - 否则返回
NotApplicable。
这样当Permit Rule不生效时,默认Deny Rule会输出Deny,最终Policy返回Deny。
补充:Not Applicable的本质含义
NotApplicable在XACML中的意思是“没有找到任何适用的规则来做出决策”,而不是“拒绝”。它代表当前请求不在这个Policy的有效管辖范围内(即使Policy的Target匹配了,但所有Rule都不生效,也会被判定为NotApplicable)。
内容的提问来源于stack exchange,提问作者Nishant

