1

决定是允许用户是否具有所需的角色。所需角色和用户当前权限为 JSON 格式。

所需权限:(另存为属性)

{
  "data": {
    "service1": {
      "service1.1": true
    },
    "service2": {
      "service2.1: false,
      "service2.2": true,
      "service2.3": false
    }
  }
}

用户当前权限:

{
  "data": {
    "service1": {
      "service1.1": true
    },
    "service2": {
      "service2.1: false,
      "service2.2": false,
      "service2.3": true
    }
  }
}

为了做出决定,我们需要检查用户是否拥有类似于所需权限的服务。在上面的示例中,用户将 data.service1.service1.1 设为 true,data.service2.service2.3 设为 true,其中所需角色 data.service1.service1.1 设为 true,data.service2.service2.2 设为是的,在这种情况下,我们否认。

我编写了单独的规则来检查每个服务,但这只是对服务组合的检查。

   rule service1.1{               
    permit
    condition               
      (allOf(function[booleanEqual], true, requiredRoles.data.service1.service1.1))
      &&
      (allOf(function[booleanEqual], true, requiredRoles.data.service1.service1.1))        
        on permit {
            advice reasonForPermit{
            reasonAttribute=   "Contains Valid services" 
            }
        }
    }

有人可以帮忙写一个 if .. 然后签入 alfa 吗?

4

2 回答 2

4

ALFA(或 XACML)中没有if..then构造。您改为使用组合算法。特别是,onPermitApplySecond是最类似于if..then构造的策略组合算法。

但是,如果您可以对属性数据做出合理的假设,通常有一种更简单的方法来表达您想要的内容。例如,在您的示例中,如果始终保证所需权限和当前权限都为每个可用服务包含一个布尔值,那么您可以编写:

rule {
    target 
        clause requiredRoles_service1_1 == false or permitted_service1_1 == true
        clause requiredRoles_service2_1 == false or permitted_service2_1 == true
        ...
    permit
}

请记住,在目标中,子句是“与”在一起的。然后,此规则检查,对于每个服务,该角色不是必需的,还是在当前权限中提供的。

相反,如果它可能发生而不存在任何这些属性(即该属性没有值),那么您必须防范这种情况。您可以使用类似以下的条件来做到这一点,但也有其他方法:

rule {
    permit
    condition
        (not(booleanIsIn(true, requiredRoles_service1_1)) || booleanIsIn(true, permitted_service1_1))
        &&
        (not(booleanIsIn(true, requiredRoles_service2_1)) || booleanIsIn(true, permitted_service2_1))
        && 
        ...
}

总而言之,如果您可以将属性数据转换为其他形式,则通常有更简单的方法来表达策略。每个服务都有一对属性,就像上面的例子一样,可能不是必需的。

如果您可以将所有必需的角色和当前权限分别收集到一个属性中,则可以更紧凑地表达该策略。假设您有两个属性,requiredRolespermittedRoles值分别列出了给定用户所需和允许的服务角色。在您的示例中,这意味着它requiredRoles具有价值,例如["service1.1", "service2.2"]并且permittedRoles具有价值["service1.1", "service2.3"]。然后你可以写一个这样的规则:

rule {
    permit
    condition stringSubSet(requiredRoles, permittedRoles)
}
于 2020-08-04T12:54:04.870 回答
0

我可以通过为每个服务创建单独的属性并使用来自所需角色的服务编写一个带有目标子句的规则来做到这一点,条件是允许角色中的服务是否为真。我使用 permitunlessDeny 算法在策略中组合了以下所有规则

rule rule1 {        
    target clause requiredRoles.service1_1 == true
    deny
    condition 
        not(permittedRoles.service1_1 == true)
       
    on permit {
        advice reasonForPermit {
            reasonAttribute= "User has valid services" 
        }
    }
}

谢谢你的建议巴勃罗。

于 2020-08-06T10:03:43.333 回答