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.