简体   繁体   中英

Complex XACML, combination and dependencies of bags

I have a XACML request like this (pseudo-xacml):

<Request>
    <Attributes Category="resource">
        <Attribute AttributeId="product">
            <AttributeValue>A</AttributeValue>
        </Attribute>
        <Attribute AttributeId="market">
            <AttributeValue>M2</AttributeValue>
            <AttributeValue>M3</AttributeValue>
        </Attribute>
        <Attribute AttributeId="slice">
            <AttributeValue>fus</AttributeValue>
            <AttributeValue>do</AttributeValue>
            <AttributeValue>rah</AttributeValue>
        </Attribute>
    </Attributes>


    <Attributes Category="subject">
        <Attribute AttributeId="product-market-slice-access">
            <AttributeValue>A:::M2:::fus</AttributeValue>
            <AttributeValue>A:::M2:::do</AttributeValue>
            <AttributeValue>A:::M2:::rah</AttributeValue>
            <AttributeValue>A:::M3:::fus</AttributeValue>
            <AttributeValue>A:::M3:::do</AttributeValue>
            <!--<AttributeValue>A:::M3:::rah</AttributeValue>--> <!-- Missing attribute, permission denied! -->
        </Attribute>
    </Attributes>

</Request>

I wish to create a policy that denies access with the above request, and permits access if the subject is given the missing attribute (commented out).

Is there a way to express this in a XACML/ALFA policy?

If there was a function in XACML that could "join" bags (think sql-join) that would be helpful. That way I could use a combination of the functions "AnyOfAll" and "String-Equal".

Pseudo-xml of wanted function:

<WantedFunction>
    <Input>
        <Separator>:::</Separator>
        <Bag>
            <AttributeValue>A</AttributeValue>
            <AttributeValue>B</AttributeValue>
        </Bag>
        <Bag>
            <AttributeValue>M2</AttributeValue>
            <AttributeValue>M3</AttributeValue>
        </Bag>
        <Bag>
            <AttributeValue>fus</AttributeValue>
            <AttributeValue>do</AttributeValue>
            <AttributeValue>rah</AttributeValue>
        </Bag>
    </Input>

    <Output>
        <Bag>
            <AttributeValue>A:::M2:::fus</AttributeValue>
            <AttributeValue>A:::M2:::do</AttributeValue>
            <AttributeValue>A:::M2:::rah</AttributeValue>
            <AttributeValue>A:::M3:::fus</AttributeValue>
            <AttributeValue>A:::M3:::do</AttributeValue>
            <AttributeValue>A:::M3:::rah</AttributeValue>
            <AttributeValue>B:::M2:::fus</AttributeValue>
            <AttributeValue>B:::M2:::do</AttributeValue>
            <AttributeValue>B:::M2:::rah</AttributeValue>
            <AttributeValue>B:::M3:::fus</AttributeValue>
            <AttributeValue>B:::M3:::do</AttributeValue>
            <AttributeValue>B:::M3:::rah</AttributeValue>
        </Bag>
    </Output>
</WantedFunction>

This is a great question and I'm glad to see you're using ALFA as well. Let me shed some light on it.

The request

First of all, in a XACML request, sending an attribute as two separate attributes is the same as sending it as a single attribute. For instance, the following two requests are the same.

Can Alice the customer who is also an employee view insurance policy 123?

Request Example 1

<?xml version="1.0" encoding="UTF-8"?><xacml-ctx:Request ReturnPolicyIdList="true" CombinedDecision="false" xmlns:xacml-ctx="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17">
   <xacml-ctx:Attributes Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" >
      <xacml-ctx:Attribute AttributeId="com.axiomatics.user.type" IncludeInResult="true">
         <xacml-ctx:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">customer</xacml-ctx:AttributeValue>
      </xacml-ctx:Attribute>
      <xacml-ctx:Attribute AttributeId="com.axiomatics.user.type" IncludeInResult="true">
         <xacml-ctx:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">employee</xacml-ctx:AttributeValue>
      </xacml-ctx:Attribute>
      <xacml-ctx:Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" IncludeInResult="true">
         <xacml-ctx:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">alice</xacml-ctx:AttributeValue>
      </xacml-ctx:Attribute>
   </xacml-ctx:Attributes>
   <xacml-ctx:Attributes Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" >
      <xacml-ctx:Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" IncludeInResult="true">
         <xacml-ctx:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">view</xacml-ctx:AttributeValue>
      </xacml-ctx:Attribute>
   </xacml-ctx:Attributes>
   <xacml-ctx:Attributes Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" >
      <xacml-ctx:Attribute AttributeId="com.axiomatics.resource.type" IncludeInResult="true">
         <xacml-ctx:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">insurance policy</xacml-ctx:AttributeValue>
      </xacml-ctx:Attribute>
      <xacml-ctx:Attribute AttributeId="com.axiomatics.policy.polId" IncludeInResult="true">
         <xacml-ctx:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">123</xacml-ctx:AttributeValue>
      </xacml-ctx:Attribute>
   </xacml-ctx:Attributes>
</xacml-ctx:Request>

Request Example 2

<?xml version="1.0" encoding="UTF-8"?><xacml-ctx:Request ReturnPolicyIdList="true" CombinedDecision="false" xmlns:xacml-ctx="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17">
   <xacml-ctx:Attributes Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" >
      <xacml-ctx:Attribute AttributeId="com.axiomatics.user.type" IncludeInResult="true">
         <xacml-ctx:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">customer</xacml-ctx:AttributeValue>
         <xacml-ctx:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">employee</xacml-ctx:AttributeValue>
      </xacml-ctx:Attribute>
      <xacml-ctx:Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" IncludeInResult="true">
         <xacml-ctx:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">alice</xacml-ctx:AttributeValue>
      </xacml-ctx:Attribute>
   </xacml-ctx:Attributes>
   <xacml-ctx:Attributes Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" >
      <xacml-ctx:Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" IncludeInResult="true">
         <xacml-ctx:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">view</xacml-ctx:AttributeValue>
      </xacml-ctx:Attribute>
   </xacml-ctx:Attributes>
   <xacml-ctx:Attributes Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" >
      <xacml-ctx:Attribute AttributeId="com.axiomatics.resource.type" IncludeInResult="true">
         <xacml-ctx:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">insurance policy</xacml-ctx:AttributeValue>
      </xacml-ctx:Attribute>
      <xacml-ctx:Attribute AttributeId="com.axiomatics.policy.polId" IncludeInResult="true">
         <xacml-ctx:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">123</xacml-ctx:AttributeValue>
      </xacml-ctx:Attribute>
   </xacml-ctx:Attributes>
</xacml-ctx:Request>

Attributes are bags

In XACML, an attribute is always a bag. It's always multi-valued even if it contains zero or one value. This means that if you want to operate on the attribute, you need to remember it's a bag. For instance, if you want to concatenate market with slice, you'd either have to convert it to a single value (and that only works if it's indeed a single value) or use higher-order functions. A higher-order function is a function that takes another function as a parameter eg AllOf.

Concatenating multi-valued attributes

An option would be to use stringConcatenate but that function only operates on atomic values. You could use map to apply it to a bag but unfortunately in your case, you would need a map capable of working on multiple bags.

The solution: using multiple decision requests

Rather than sending all the values in one lump request, you could use the Multiple Decision Profile (MDP) which lets you send multiple requests in one go for instance:

Can Alice view, edit, delete record 1,2,3?

The answer would contain as many decisions as the product of the combinations (1x3x3 in this case).

In your case, you would combine all the decisions into a single one. If all Permit then Permit else Deny. There is a parameter in MDP to do that. It's called CombinedDecision .

With that in mind, here's what the policy will look like (using ALFA notation):

namespace com.axiomatics{
    attribute product{
        category = resourceCat
        id = "product"
        type = string
    }
    attribute market{
        category = resourceCat
        id = "market"
        type = string
    }
    attribute slice{
        category = resourceCat
        id = "slice"
        type = string
    }

    attribute productMarketSliceAccess{
        category = subjectCat
        id = "product-market-slice-access"
        type = string
    }

    policy userAccessProductMarketSlice{
        apply firstApplicable
        rule allowAccess{
            permit
            condition stringIsIn(stringOneAndOnly(product)+
                                 stringOneAndOnly(market)+
                                 stringOneAndOnly(slice),productMarketSliceAccess)
        }
    }
}

Sample Request - MDP

{
    "Request": {
        "CombinedDecision": true,
        "AccessSubject": {
            "Attribute": [
                {
                    "AttributeId": "product-market-slice-access",
                    "Value": "BAC"
                },
                {
                    "AttributeId": "product-market-slice-access",
                    "Value": "DEF"
                }
            ]
        },
        "Resource": [{
            "Attribute": [
                {
                    "AttributeId": "market",
                    "Value": "A"
                },
                {
                    "AttributeId": "product",
                    "Value": "B"
                },
                {
                    "AttributeId": "slice",
                    "Value": "C"
                }
            ]
        },{
            "Attribute": [
                {
                    "AttributeId": "market",
                    "Value": "E"
                },
                {
                    "AttributeId": "product",
                    "Value": "D"
                },
                {
                    "AttributeId": "slice",
                    "Value": "F"
                }
            ]
        }],
        "Action": {
            "Attribute": []
        },
        "Environment": {
            "Attribute": []
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM