XACML Attribute Locator using the Database

     

    << Go Back To MAIN XACML Article Dashboard

     

    Availability

    This feature will be available as part of JBossXACML v2.0.5

     

    You can pick up an intermediate release using this jar.


    Note: You will need to remove any jboss-xacml.jar, jboss-sunxacml.jar, jbossxacml.jar and replace with this jbossxacml-2.0.5.CR1.March02.jar

    What is an XACML Attribute Locator?

    When the PDP has to make a decision, if any attributes required for the decision is not provided as part of the XACML request, the PDP will ask the configured Attribute Locators to provide information on the missing attribute.

     

    Database Attribute Locators

     

    A missing attribute may be part of the XACML Subject, Resource, Environment or an Action. The administrator has to appropriately configure the available Database Attribute Locators.

     

    The locators are:

    • org.jboss.security.xacml.locators.attrib.DatabaseResourceAttributeLocator
    • org.jboss.security.xacml.locators.attrib.DatabaseSubjectAttributeLocator
    • org.jboss.security.xacml.locators.attrib.DatabaseActionAttributeLocator
    • org.jboss.security.xacml.locators.attrib.DatabaseEnvAttributeLocator

     

    Configuration

     

    All the above locators have the following options common.

    • DATABASE_FILE_NAME : Location of a database related properties file.
    • sql  : A SQL Prepared Statement that will retrieve one column from the database.
    • attributeSupportedId : Attribute that is supported by this locator for retrieval.
    • preparedStatementValue : This is the URI of the attribute available from the request that will be plugged into the prepared statement wildcard.
    • valueDataType: The data type of the attribute that is being plugged into the prepared statement.
    • columnName: column name from where the attribute is retrieved from the database.  (NOTE: this should be the same as the column in the prepared sql statement above).

     

    The following option is what is different in the locators.

    • name : the fully qualified name (FQN) of the class.

     

     

    Examples

     

    Prerequisite

    I assume that you have a good understanding of

    • the JBossXACML Config file.
    • the XACML Policy Structure.
    • the XACML Request Structure.

     

    If any of the above pre-requisites are not met, I strongly suggest you familiarize yourself with that.

     

     

    I have a JUnit Test Class that you can take a look if you want to.  JUnit Test

     

    Let us use a single policy for the two examples below:

     

    <?xml version="1.0" encoding="UTF-8"?>
    <Policy 
        xmlns="urn:oasis:names:tc:xacml:2.0:policy:schema:os" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="urn:oasis:names:tc:xacml:2.0:policy:schema:os 
          http://docs.oasis-open.org/xacml/access_control-xacml-2.0-policy-schema-os.xsd" 
        PolicyId="urn:xacml:2.0:interop:example:policyid:02" 
        RuleCombiningAlgId=
          "urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:permit-overrides">
      <Description>
        XACML 2.0 Interop Example Policy 02: Only allow a customer whose id matches the 
          account owner-id to access the account and only if the account status is active.
          Only allow trades that have value within credit-line and trade-limit restrictions.
      </Description>
      <Target/>
      <VariableDefinition VariableId="urn:xacml:2.0:interop:example:variableid:01.2">
        <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
          <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
            <SubjectAttributeDesignator 
                AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" 
                DataType="http://www.w3.org/2001/XMLSchema#string"/>
          </Apply>
          <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
            <ResourceAttributeDesignator 
                AttributeId="urn:xacml:2.0:interop:example:resource:owner-id" 
                DataType="http://www.w3.org/2001/XMLSchema#string"/>
          </Apply>
        </Apply>
      </VariableDefinition>
      <VariableDefinition VariableId="urn:xacml:2.0:interop:example:variableid:02">
        <!--  Function to evaluate:                                           -->
        <!--       ((buy-num-shares x buy-offer-price) lt                     --> 
        <!--                             (credit-line - current-credit) ) and -->
        <!--       ((buy-num-shares x buy-offer-price) lt trade-limit)        -->
        <!--  If both the above expressions true, then Request within limits  -->
        <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
          <Apply FunctionId=
              "urn:oasis:names:tc:xacml:1.0:function:integer-less-than-or-equal">
            <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-multiply">
             <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
              <SubjectAttributeDesignator 
                  AttributeId="urn:xacml:2.0:interop:example:subject:buy-num-shares" 
                  DataType="http://www.w3.org/2001/XMLSchema#integer"/>
             </Apply>
             <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
              <SubjectAttributeDesignator 
                  AttributeId="urn:xacml:2.0:interop:example:subject:buy-offer-price" 
                  DataType="http://www.w3.org/2001/XMLSchema#integer"/>
             </Apply>
            </Apply>
            <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-subtract">
             <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
              <ResourceAttributeDesignator 
                AttributeId="urn:xacml:2.0:interop:example:resource:credit-line" 
                DataType="http://www.w3.org/2001/XMLSchema#integer"/>
             </Apply>
             <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
              <ResourceAttributeDesignator 
                AttributeId="urn:xacml:2.0:interop:example:resource:current-credit" 
                DataType="http://www.w3.org/2001/XMLSchema#integer"/>
             </Apply>
            </Apply>
          </Apply>
          <Apply FunctionId=
              "urn:oasis:names:tc:xacml:1.0:function:integer-less-than-or-equal">
            <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-multiply">
             <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
              <SubjectAttributeDesignator 
                  AttributeId="urn:xacml:2.0:interop:example:subject:buy-num-shares" 
                  DataType="http://www.w3.org/2001/XMLSchema#integer"/>
             </Apply>
             <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
              <SubjectAttributeDesignator 
                  AttributeId="urn:xacml:2.0:interop:example:subject:buy-offer-price" 
                  DataType="http://www.w3.org/2001/XMLSchema#integer"/>
             </Apply>
            </Apply>
            <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
             <ResourceAttributeDesignator 
                AttributeId="urn:xacml:2.0:interop:example:resource:trade-limit" 
                DataType="http://www.w3.org/2001/XMLSchema#integer"/>
            </Apply>
          </Apply>
        </Apply>
      </VariableDefinition>
      <Rule RuleId="urn:xacml:2.0:interop:example:ruleid:02" 
          Effect="Permit">
        <Description>
          XACML 2.0 Interop Example Rule 02: Only allow a customer whose id matches the 
            account owner-id to access the account and only if the account status is active.
        </Description>
        <Target>
          <!-- This rule permits access to CustomerAccount resources -->
          <Resources>
            <!-- CustomerAccount -->
            <Resource>
              <ResourceMatch 
                  MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
                <AttributeValue 
                    DataType="http://www.w3.org/2001/XMLSchema#string"
                      >CustomerAccount</AttributeValue>
                <ResourceAttributeDesignator 
                    AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id"
                    DataType="http://www.w3.org/2001/XMLSchema#string"/>
              </ResourceMatch>
              <!-- Account must have Active status -->
              <ResourceMatch 
                  MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
                <AttributeValue 
                    DataType="http://www.w3.org/2001/XMLSchema#string"
                      >Active</AttributeValue>
                <ResourceAttributeDesignator 
                    AttributeId="urn:xacml:2.0:interop:example:resource:account-status"
                    DataType="http://www.w3.org/2001/XMLSchema#string"/>
              </ResourceMatch>
            </Resource>
          </Resources>
          <!-- This rule only applies to the ViewAccount action -->
          <Actions>
            <Action>
              <ActionMatch
                  MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
                <AttributeValue
                    DataType="http://www.w3.org/2001/XMLSchema#string"
                      >Buy</AttributeValue>
                <ActionAttributeDesignator
                    AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"
                    DataType="http://www.w3.org/2001/XMLSchema#string"/>
              </ActionMatch>
            </Action>
          </Actions>
        </Target>
        <Condition>
          <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
            <VariableReference VariableId="urn:xacml:2.0:interop:example:variableid:01.2"/>
            <VariableReference VariableId="urn:xacml:2.0:interop:example:variableid:02"/>
          </Apply>
        </Condition>
      </Rule>
      <Rule RuleId="urn:xacml:2.0:interop:example:ruleid:deny02" Effect="Deny">
        <Description>
          This Policy is permit-overrides, therefore if a rule above evaluated to
          Permit this Rule will be skipped. However, if no Permit was obtained, this
          Rule evaluates to true and so produces a Deny. Therefore evaluation of this
          Policy results in either a Permit or Deny which is the intended effect.          
        </Description>
        <Target/>
      </Rule>
      <Obligations>
        <!-- These obligations tell PEP to provide specific data items to the response -->
        <!-- This obligation says provide the xacml:Decision data to the response -->
        <Obligation
            ObligationId="urn:xacml:2.0:interop:example:obligation:decision"
            FulfillOn="Permit"/>
        <!-- This obligation says provide the xacml:StatusCode data to the response -->
        <Obligation
            ObligationId="urn:xacml:2.0:interop:example:obligation:status-code"
            FulfillOn="Permit"/>
        <!-- This obligation says provide the xacml:StatusMessage data to the response -->
        <Obligation
            ObligationId="urn:xacml:2.0:interop:example:obligation:status-message"
            FulfillOn="Permit"/>
        <!-- This obligation says provide the xacml:Decision data to the response -->
        <Obligation
            ObligationId="urn:xacml:2.0:interop:example:obligation:decision"
            FulfillOn="Deny"/>
        <!-- This obligation says provide the xacml:StatusCode data to the response -->
        <Obligation
            ObligationId="urn:xacml:2.0:interop:example:obligation:status-code"
            FulfillOn="Deny"/>
        <!-- This obligation says provide the xacml:StatusMessage data to the response -->
        <Obligation
            ObligationId="urn:xacml:2.0:interop:example:obligation:status-message"
            FulfillOn="Deny"/>
      </Obligations>
    </Policy>
    

     

     

    We will have a common db.properties:

     

    In this example, I am using HSQL.

     

    The Tomcat JDBCRealm page has some good details on how the following properties file may look for various databases.

     

    driverName=org.hsqldb.jdbcDriver
    connectionURL=jdbc:hsqldb:target/XACMLDBAttributeLocator
    

     

    Case 1:  The XACML Request comes with a missing attribute in the resource element.

    Note that the attribute that is missing is commented out for viewer's benefit.

    The attribute missing from the request is "urn:xacml:2.0:interop:example:resource:account-status"

     

    <?xml version="1.0" encoding="UTF-8"?>
    <xacml-context:Request 
        xmlns:xacml-context="urn:oasis:names:tc:xacml:2.0:context:schema:os" 
        xmlns="urn:oasis:names:tc:xacml:2.0:context:schema:os" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation=" urn:oasis:names:tc:xacml:2.0:context:schema:os 
          http://docs.oasis-open.org/xacml/access_control-xacml-2.0-context-schema-os.xsd">
      <Subject 
          SubjectCategory="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject">
        <Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"
            DataType="http://www.w3.org/2001/XMLSchema#string" Issuer="xacml20.interop.com">
          <AttributeValue>123456</AttributeValue>
        </Attribute>
        <Attribute AttributeId="urn:xacml:2.0:interop:example:subject:user-name"
            DataType="http://www.w3.org/2001/XMLSchema#string" Issuer="xacml20.interop.com">
          <AttributeValue>John Smith</AttributeValue>
        </Attribute>
        <Attribute AttributeId="urn:xacml:2.0:interop:example:subject:buy-num-shares"
            DataType="http://www.w3.org/2001/XMLSchema#integer"
            Issuer="xacml20.interop.com">
          <AttributeValue>1000</AttributeValue>
        </Attribute>
        <Attribute AttributeId="urn:xacml:2.0:interop:example:subject:buy-offer-price"
            DataType="http://www.w3.org/2001/XMLSchema#integer"    
            Issuer="xacml20.interop.com">
          <AttributeValue>1</AttributeValue>
        </Attribute>
        <Attribute AttributeId="urn:xacml:2.0:interop:example:subject:req-credit-ext-approval"
            DataType="http://www.w3.org/2001/XMLSchema#string" Issuer="xacml20.interop.com">
          <AttributeValue>false</AttributeValue>
        </Attribute>
        <Attribute AttributeId="urn:xacml:2.0:interop:example:subject:req-trade-approval"
            DataType="http://www.w3.org/2001/XMLSchema#string" Issuer="xacml20.interop.com">
          <AttributeValue>false</AttributeValue>
        </Attribute>
      </Subject>
      <Resource>
        <Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" 
            DataType="http://www.w3.org/2001/XMLSchema#string">
          <AttributeValue>CustomerAccount</AttributeValue>
        </Attribute>
        <Attribute AttributeId="urn:xacml:2.0:interop:example:resource:owner-id" 
            DataType="http://www.w3.org/2001/XMLSchema#string">
          <AttributeValue>123456</AttributeValue>
        </Attribute>
        <Attribute AttributeId="urn:xacml:2.0:interop:example:resource:owner-name" 
            DataType="http://www.w3.org/2001/XMLSchema#string">
          <AttributeValue>John Smith</AttributeValue>
        </Attribute>
        
        <!-- WE GET THIS VIA THE ATTRIBUTE LOCATOR 
        <Attribute AttributeId="urn:xacml:2.0:interop:example:resource:account-status"
            DataType="http://www.w3.org/2001/XMLSchema#string">
          <AttributeValue>Active</AttributeValue>
        </Attribute>
         -->
        
        <Attribute AttributeId="urn:xacml:2.0:interop:example:resource:credit-line"
            DataType="http://www.w3.org/2001/XMLSchema#integer">
          <AttributeValue>15000</AttributeValue>
        </Attribute>
        <Attribute AttributeId="urn:xacml:2.0:interop:example:resource:current-credit"
            DataType="http://www.w3.org/2001/XMLSchema#integer">
          <AttributeValue>10000</AttributeValue>
        </Attribute>
        <Attribute AttributeId="urn:xacml:2.0:interop:example:resource:trade-limit"
            DataType="http://www.w3.org/2001/XMLSchema#integer">
          <AttributeValue>10000</AttributeValue>
        </Attribute>
      </Resource>
      <Action>
        <Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"
            DataType="http://www.w3.org/2001/XMLSchema#string">
          <AttributeValue>Buy</AttributeValue>
        </Attribute>
      </Action>
      <Environment/>
    </xacml-context:Request>
    

     

    Given this request file, you may want to take a look at the JBossXACML config file that we will use.

     

    <ns:jbosspdp xmlns:ns="urn:jboss:xacml:2.0">
      <ns:Policies>
        <ns:Policy>
          <ns:Location>locators/attrib/attribLocator_policy.xml</ns:Location> 
        </ns:Policy>
      </ns:Policies>
      <ns:Locators>
        <ns:Locator Name="org.jboss.security.xacml.locators.JBossPolicyLocator"/>
        <ns:Locator Name="org.jboss.security.xacml.locators.attrib.DatabaseResourceAttributeLocator">   
          <ns:Option Name="DATABASE_FILE_NAME">data_stores/db.properties</ns:Option>  
          <ns:Option Name="sql">SELECT account_status FROM resource where owner_id=?;</ns:Option>  
          <ns:Option Name="attributeSupportedId">urn:xacml:2.0:interop:example:resource:account-status</ns:Option> 
          <ns:Option Name="preparedStatementValue">urn:xacml:2.0:interop:example:resource:owner-id</ns:Option>  
          <ns:Option Name="valueDataType">http://www.w3.org/2001/XMLSchema#string</ns:Option>   
          <ns:Option Name="columnName">account_status</ns:Option> 
        </ns:Locator> 
      </ns:Locators>
    </ns:jbosspdp>
    

     

    Case 2: When the request is missing a Subject attribute.

     

    Let us take a look at the request. Like before, the attribute that will be missing from the request (and will be supplied by the DB attribute locator) is commented out for the viewer's benefit.

     

    The attribute missing from the request is "urn:oasis:names:tc:xacml:1.0:subject:subject-id".

     

    <?xml version="1.0" encoding="UTF-8"?>
    <xacml-context:Request 
        xmlns:xacml-context="urn:oasis:names:tc:xacml:2.0:context:schema:os" 
        xmlns="urn:oasis:names:tc:xacml:2.0:context:schema:os" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation=" urn:oasis:names:tc:xacml:2.0:context:schema:os 
          http://docs.oasis-open.org/xacml/access_control-xacml-2.0-context-schema-os.xsd">
      <Subject 
          SubjectCategory="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject">
          
       <!--  WE GET THIS VIA THE SUBJECT ATTRIBUTE LOCATOR
        <Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"
            DataType="http://www.w3.org/2001/XMLSchema#string" Issuer="xacml20.interop.com">
          <AttributeValue>123456</AttributeValue>
        </Attribute>
         -->
         
         
        <Attribute AttributeId="urn:xacml:2.0:interop:example:subject:user-name"
            DataType="http://www.w3.org/2001/XMLSchema#string" Issuer="xacml20.interop.com">
          <AttributeValue>John Smith</AttributeValue>
        </Attribute>
        <Attribute AttributeId="urn:xacml:2.0:interop:example:subject:buy-num-shares"
            DataType="http://www.w3.org/2001/XMLSchema#integer"
            Issuer="xacml20.interop.com">
          <AttributeValue>1000</AttributeValue>
        </Attribute>
        <Attribute AttributeId="urn:xacml:2.0:interop:example:subject:buy-offer-price"
            DataType="http://www.w3.org/2001/XMLSchema#integer"    
            Issuer="xacml20.interop.com">
          <AttributeValue>1</AttributeValue>
        </Attribute>
        <Attribute AttributeId="urn:xacml:2.0:interop:example:subject:req-credit-ext-approval"
            DataType="http://www.w3.org/2001/XMLSchema#string" Issuer="xacml20.interop.com">
          <AttributeValue>false</AttributeValue>
        </Attribute>
        <Attribute AttributeId="urn:xacml:2.0:interop:example:subject:req-trade-approval"
            DataType="http://www.w3.org/2001/XMLSchema#string" Issuer="xacml20.interop.com">
          <AttributeValue>false</AttributeValue>
        </Attribute>
      </Subject>
      <Resource>
        <Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" 
            DataType="http://www.w3.org/2001/XMLSchema#string">
          <AttributeValue>CustomerAccount</AttributeValue>
        </Attribute>
        <Attribute AttributeId="urn:xacml:2.0:interop:example:resource:owner-id" 
            DataType="http://www.w3.org/2001/XMLSchema#string">
          <AttributeValue>123456</AttributeValue>
        </Attribute>
        <Attribute AttributeId="urn:xacml:2.0:interop:example:resource:owner-name" 
            DataType="http://www.w3.org/2001/XMLSchema#string">
          <AttributeValue>John Smith</AttributeValue>
        </Attribute>
        
        <Attribute AttributeId="urn:xacml:2.0:interop:example:resource:account-status"
            DataType="http://www.w3.org/2001/XMLSchema#string">
          <AttributeValue>Active</AttributeValue>
        </Attribute> 
        
        <Attribute AttributeId="urn:xacml:2.0:interop:example:resource:credit-line"
            DataType="http://www.w3.org/2001/XMLSchema#integer">
          <AttributeValue>15000</AttributeValue>
        </Attribute>
        <Attribute AttributeId="urn:xacml:2.0:interop:example:resource:current-credit"
            DataType="http://www.w3.org/2001/XMLSchema#integer">
          <AttributeValue>10000</AttributeValue>
        </Attribute>
        <Attribute AttributeId="urn:xacml:2.0:interop:example:resource:trade-limit"
            DataType="http://www.w3.org/2001/XMLSchema#integer">
          <AttributeValue>10000</AttributeValue>
        </Attribute>
      </Resource>
      <Action>
        <Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"
            DataType="http://www.w3.org/2001/XMLSchema#string">
          <AttributeValue>Buy</AttributeValue>
        </Attribute>
      </Action>
      <Environment/>
    </xacml-context:Request>
    

     

    The JBossXACML config file will look as follows:

    <ns:jbosspdp xmlns:ns="urn:jboss:xacml:2.0">
      <ns:Policies>
        <ns:Policy>
          <ns:Location>locators/attrib/attribLocator_policy.xml</ns:Location> 
        </ns:Policy>
      </ns:Policies>
      <ns:Locators>
        <ns:Locator Name="org.jboss.security.xacml.locators.JBossPolicyLocator"/>
        <ns:Locator Name="org.jboss.security.xacml.locators.attrib.DatabaseSubjectAttributeLocator">   
          <ns:Option Name="DATABASE_FILE_NAME">data_stores/db.properties</ns:Option>  
          <ns:Option Name="sql">SELECT subject_id FROM subject where name=?;</ns:Option>  
          <ns:Option Name="attributeSupportedId">urn:oasis:names:tc:xacml:1.0:subject:subject-id</ns:Option> 
          <ns:Option Name="preparedStatementValue">urn:xacml:2.0:interop:example:subject:user-name</ns:Option>  
          <ns:Option Name="valueDataType">http://www.w3.org/2001/XMLSchema#string</ns:Option>   
          <ns:Option Name="columnName">subject_id</ns:Option> 
        </ns:Locator> 
      </ns:Locators>
    </ns:jbosspdp>
    

     

    Conclusion

     

    The Database locators can retrieve one attribute at a time. Multiple attributes that need to be retrieved from the database will require a stacked set of locators.