Page 1
Standard

How to send a XACML request using cURL – the world’s smallest Policy Enforcement Point

Recently, I’ve been asked to write a policy enforcement point (PEP) in Perl. I haven’t touched Perl in a long while but I remember having had fun using it to parse documents on a file system back in 2003 when working at the Natural Languages Lab at BT Adastral Park.
I started looking around at different resources. The obvious ones are:

  • http://www.perl.org/: the home of all Perl resources.
  • ActiveState Perl: possibly the de facto Perl distribution
  • Perlmonks: a great Perl forum where I used to hang out, and
  • Perl for Eclipse: EPIC, the Perl Editor and IDE for Eclipse – pretty much all I do these days is in and around Eclipse (from SQL and LDAP to ALFA, the Axiomatics Language for Authorization) so it seemed natural to add Perl to my Eclipse Swiss army knife.

Then, of course, it didn’t take me long to stumble upon cURL. cURL is one of those tools you just know, a bit like wget or basic Linux / Unix commands.

I then realized I could simply use cURL to post a XACML request to a Policy Decision Point. And that’s exactly what I tried. I had to fiddle around with the different options before I got it right. Here’s the outcome:

C:\temp>curl -X POST -H 'Content-type:text/xml' -T soap-xacml-request.xml https://localhost:8443/asm-pdp/pdp --cacert pdp.b64.cer --user pep:password
Let’s have a look at the different options:

  • -X : use this to indicate the HTTP method, i.e. POST in this case.
  • -H : use this to indicate custom headers, in this case Content-type:text/xml.
  • -T : use this to point to the file containing the payload to be sent, i.e. the XACML request optionally wrapped in a SOAP request if the targeted service is SOAP-based.
  • –cacert : use this to indicate the trusted certificate. Download the target server’s public key and use that in PEM format (base 64-encoded).
  • –user : use this to indicate the username and password to be used, if any, e.g. in the case of HTTP Basic Authentication.

Great, I can now send a XACML request in less characters than a tweet requires. Sure enough, playing around with cURL diverted me from my original intent – writing a PEP in Perl. I guess PPEP will have to wait…

Here’s the sample XACML request I sent:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body>
        <irc:AccessQuery3
            xmlns:irc="http://axiomatics.com/delegent/pdpsimple/v5/AccessQuery3">
            <xacml-ctx:Request ReturnPolicyIdList="false"
                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:3.0:attribute-category:action">
                    <xacml-ctx:Attribute AttributeId="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="urn:oasis:names:tc:xacml:1.0:resource:resource-type"
                        IncludeInResult="true">
                        <xacml-ctx:AttributeValue
                            DataType="http://www.w3.org/2001/XMLSchema#string">
                            book
                        </xacml-ctx:AttributeValue>
                    </xacml-ctx:Attribute>
                </xacml-ctx:Attributes>
                <xacml-ctx:Attributes
                    Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject">
                    <xacml-ctx:Attribute AttributeId="username"
                        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:Request>
        </irc:AccessQuery3>
    </soap:Body>

and the response:

<?xml version='1.0' encoding='UTF-8'?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><ns6:AccessQuery3Response xmlns:ns2="http://axiomatics.com/delegent/pdpsimple/v5/TraceAccessQuery3" xmlns:ns3="http://axiomatics.com/delegent/pdpsimple/v5/InvalidateAttributeCache" xmlns:ns4="http://axiomatics.com/delegent/pdpsimple/v5/TraceAccessQuery2" xmlns:ns5="http://axiomatics.com/delegent/pdpsimple/v5/AccessQuery2" xmlns:ns6="http://axiomatics.com/delegent/pdpsimple/v5/AccessQuery3" xmlns:ns7="urn:oasis:names:tc:xacml:2.0:context:schema:os" xmlns:ns8="urn:oasis:names:tc:xacml:2.0:policy:schema:os" xmlns:ns9="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" xmlns:ns10="http://axiomatics.com/delegent/pdpsimple/v5/faults"><xacml-ctx:Response xmlns:xacml-ctx="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17">
  <xacml-ctx:Result>
    <xacml-ctx:Decision>Deny</xacml-ctx:Decision>
    <xacml-ctx:Status>
      <xacml-ctx:StatusCode Value="urn:oasis:names:tc:xacml:1.0:status:ok"/>
    </xacml-ctx:Status>
    <xacml-ctx:Attributes Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action">
      <xacml-ctx:Attribute AttributeId="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="urn:oasis:names:tc:xacml:1.0:resource:resource-type" IncludeInResult="true">
        <xacml-ctx:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">
                            book
                        </xacml-ctx:AttributeValue>
      </xacml-ctx:Attribute>
    </xacml-ctx:Attributes>
    <xacml-ctx:Attributes Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject">
      <xacml-ctx:Attribute AttributeId="username" 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:Result>
</xacml-ctx:Response></ns6:AccessQuery3Response></S:Body></S:Envelope>
Standard

Call out to a XACML Policy Decision Point (PDP) from PHP

Today, I have the pleasure to invite a fellow colleague, Patrick McDowell, to post on my blog. Today’s topic is around reaching out to other languages other than just Java and C# for XACML-based authorization. Today’s choice? PHP, naturellement as both Patrick and I are huge WordPress fans.

If you have been programming in PHP it is very likely that you have interacted with an external authentication service. For example Google and Facebook provide external authentication services that people can use to allow other providers to authenticate users for you using standard protocols such as SAML, OAuth, and OpenID.
Once a user has been authenticated, we then need to determine what that user is authorized to do inside of an application or service. This authorization logic can be externalized and defined using a standard language called XACML.
XACML stands for eXtensible Access Control Markup Language. The standard defines a declarative access control policy language implemented in XML and a processing model describing how to evaluate authorization requests according to the rules defined in policies.
Unlike the typical role-based security methodology used in many applications XACML authorization decisions are made in real time, and are made based on attributes about the user, the resource, and the context. For example a bank teller might have access to an account but should not be permitted to access his or her own account; the teller should not have access to accounts outside of his or her bank. XACML policies can be evaluated in real time to determine whether the teller should be permitted to access an account.
Additionally authorization decisions are made externally from the application, therefore security policy is not hardcoded into the application, which makes it easier for security policies to be changed. and Security administrators gain easier access to the authorization logic.
XACML requests include:

  • Subject
  • Action
  • Resource
  • Environment

And the XACML Policy Server (PDP, aka Policy Decision Point), will return:

  • Decision (Deny, Permit, Indeterminate, Not Applicable)
  • Status
  • Obligations or Advice

To keep this simple, we are simply going to ask the XACML Authorization server to confirm that:
Users with Teller Role (Subject), can View (Action), Bank Accounts (Resource)
This request in raw XACML looks like this:

<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="http://www.axiomatics.com/acs/role" IncludeInResult="true">
         <xacml-ctx:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">teller</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:environment" >
   </xacml-ctx:Attributes>
   <xacml-ctx:Attributes Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" >
      <xacml-ctx:Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" IncludeInResult="true">
         <xacml-ctx:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">bank account</xacml-ctx:AttributeValue>
      </xacml-ctx:Attribute>
   </xacml-ctx:Attributes>
</xacml-ctx:Request>

The same request can be produced in PHP with SOAP like this:

$regReq = new stdClass();

$regReq->Version = "3.0";
$regReq->ID = "abcde1234";
$regReq->ReturnContext = true;
$regReq->Request = new stdClass();
$regReq->Request->ReturnPolicyIdList="true";
$regReq->Request->CombinedDecision="false";

$regReq->Request->Attributes = array();

$regReq->Request->Attributes[0]= new stdClass();
$regReq->Request->Attributes[0]->Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject";
$regReq->Request->Attributes[0]->Attribute = new stdClass();
$regReq->Request->Attributes[0]->Attribute->AttributeId = "http://www.axiomatics.com/acs/role";
$regReq->Request->Attributes[0]->Attribute->AttributeValue = new stdClass();
$regReq->Request->Attributes[0]->Attribute->AttributeValue->DataType="http://www.w3.org/2001/XMLSchema#string";
$regReq->Request->Attributes[0]->Attribute->AttributeValue->any="teller";

$regReq->Request->Attributes[1]= new stdClass();
$regReq->Request->Attributes[1]->Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"; 
$regReq->Request->Attributes[1]->Attribute = new stdClass();
$regReq->Request->Attributes[1]->Attribute->AttributeId = "urn:oasis:names:tc:xacml:1.0:action:action-id";
$regReq->Request->Attributes[1]->Attribute->AttributeValue = new stdClass();
$regReq->Request->Attributes[1]->Attribute->AttributeValue->DataType="http://www.w3.org/2001/XMLSchema#string";
$regReq->Request->Attributes[1]->Attribute->AttributeValue->any="view";

$regReq->Request->Attributes[2]= new stdClass();
$regReq->Request->Attributes[2]->Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"; 
$regReq->Request->Attributes[2]->Attribute = new stdClass();
$regReq->Request->Attributes[2]->Attribute->AttributeId = "urn:oasis:names:tc:xacml:1.0:resource:resource-id";
$regReq->Request->Attributes[2]->Attribute->AttributeValue = new stdClass();
$regReq->Request->Attributes[2]->Attribute->AttributeValue->DataType="http://www.w3.org/2001/XMLSchema#string";
$regReq->Request->Attributes[2]->Attribute->AttributeValue->any="bank account";
 
$regReq->Request->Attributes[3]= new stdClass();
$regReq->Request->Attributes[3]->Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment";

The following PHP code creates the WS client and sends the request to the PDP.

ini_set('soap.wsdl_cache_enabled', 0); // Turn off the cache if you like
$client = new SoapClient("http://axiomatics:8080/asm-pdp/pdp?WSDL", Array("trace" => 1));
$result = $client->AccessQuery3($regReq);

The result returns a stdClass like this:

stdClass Object ( [Response] => stdClass Object ( [Result] => stdClass Object ( [Decision] => Permit [Status] => stdClass Object ( [StatusCode] => stdClass Object ( [Value] => urn:oasis:names:tc:xacml:1.0:status:ok ) ) ) ) )

The response to this request will return an object called Result with a field labeled Decision set to Permit, as well as other information about the request such as Obligations / Advice and information about the request.
To handle the response in PHP, all you need is the following code snippet:

if ( $result->Response->Result->Decision == "Permit") { 
 echo "Permit.. Tellers can view bank accounts";
}  

The response does depend on the policy, and if the request did not find an appropriate target it is possible the response could be NotApplicable, which essentially means the Policy Decision Point (PDP), did not have enough information to make a decision.
The XACML Policy is also written in XML, and look like this in Raw XML:

<xacml3:Policy xmlns:xacml3="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="http://www.axiomatics.com/automatic-unique-id/5ec8c01d-456c-4800-b28b-ad3d289ecba3" Version="1.0" RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-unless-permit">
<xacml3:PolicyDefaults><xacml3:XPathVersion>http://www.w3.org/TR/1999/REC-xpath-19991116</xacml3:XPathVersion></xacml3:PolicyDefaults>
  <xacml3:Target>
    <xacml3:AnyOf>
      <xacml3:AllOf>
        <xacml3:Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
          <xacml3:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">bank account</xacml3:AttributeValue>
          <xacml3:AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"  AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
        </xacml3:Match>
        <xacml3:Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
          <xacml3:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">view</xacml3:AttributeValue>
          <xacml3:AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"  AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
        </xacml3:Match>
        <xacml3:Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
          <xacml3:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">teller</xacml3:AttributeValue>
          <xacml3:AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"  AttributeId="http://www.axiomatics.com/acs/role" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
        </xacml3:Match>
      </xacml3:AllOf>
    </xacml3:AnyOf>
  </xacml3:Target>
  <xacml3:Rule RuleId="51179cb3-5319-4a35-a13e-ac1db27b5d93" Effect="Permit">
    <xacml3:Description>doctor can view medicalrecord</xacml3:Description>
    <xacml3:Target/>
  </xacml3:Rule>
  <xacml3:Rule RuleId="a2af1648-41c0-4843-ba4f-c1284d367957" Effect="Deny">
    <xacml3:Target/>
  </xacml3:Rule>
</xacml3:Policy>

If you don’t like working with raw XML, Axiomatics offers an Eclipse Plug-in which uses a “Pseudocode” called ALFA (Axiomatics Language for Authorization) which makes writing these policies much simpler. It can be downloaded for free here.

Standard

A neat MS SQL treat: convert from count(*) to a bit (or boolean)

I was busy writing a sample application for a retail company where I wanted to express a XACML authorization policy that would state that a user can sell an item if it hasn’t already been sold.
I knew whether the item was sold by simply running a SQL PIP retrieving the count(*) of that item id in the sales contracts. But I wanted to have a boolean attribute in the XACML policy:
A user can sell if the item is not sold (i.e. sold==false). So I went looking around for a means to convert count(*) into a MS SQL bit (the boolean datatype).

And the answer is:

select cast(count(*) as bit) as sold from salecontracts where identifier='9700E2EA-8545-4F26-91A1-1F5E7953E3A4'

Standard

Fine-grained access control using XACML in C# applications and the .Net framework

Background

When I talk to customers, I see an increase in interest in XACML for the .Net framework and the C# language. Historically, all XACML implementations have been in Java, most of them stemming from SunXACML. It is the case for instance of WSO2’s offering, SICSACML, and of course Axiomatics’ Policy Server.

Support for XACML in C#

Axiomatics and other companies have since released .Net PDPs and cover the space fairly well. In addition, it is possible to develop WS clients to SOAP-based PDPs regardless of the technology used.

A simple tutorial

The tutorial hereafter focuses on a C# example built using svcutil and the Axiomatics Policy Server’s SOAP-based PDP. With this code, it is therefore possible to invoke the Java-based SOAP-based web service from any .Net application.

Pre-requisites

Before you get started, you will need the .Net framework 3+ as well as the Axiomatics Policy Server. You can download them here:

Generating the .Net client stub

The .Net framework comes with a little utility called svcutil. This utility can generate client stubs from a WSDL such as the one that comes with the Axiomatics Policy Server. Using svcutil (or the add service reference… option in Visual Studio), let’s generate the client stub.

Add Service Reference in C# .Net - MS Visual Studio

Use the Add Service Reference to generate a C# client stub for the Axiomatics Policy Decision Point.


This will bring up the following dialog where one can type in the path to a WSDL that describes any service for which one wants to create a client stub. In our case we can browse to our PDP service. In this example, the Axiomatics PDP is running locally inside an Apache Tomcat 7 web server. It is exposed as a SOAP web service.
The Add Service Reference… will scan the WSDL and display the available operations. We can inspect the different operations and eventually click on OK (after possibly changing the namespace for the newly generated client). Clicking on OK will lead to:

  • the generation of a C# file called Reference.cs which contains the client stub and serialization code.
  • the creation of a default configuration file, App.config, which contains the configuration for the endpoint such as the URL, the type of security and binding as well the message formatting. You can find more information on these files at Microsoft.
Add a service reference and generate a client stub from a WSDL in Visual Studio 2010

Use the Add Service Reference to browse to the PDP's WSDL and add a C# client stub.

We can now start writing a few lines of code to see how the client behaves. The code svcutil automatically generates is a direct mirror of the WSDL. This means the objects we can work with are objects defined in the WSDL. Let’s get started with a simple example. Let’s first create a standard C# class as below

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace com.axiomatics.sample.pep
{
    class PepC
    {
    }
}

What we now want to do is add a main method and an instance of the service reference we just added to our project. We can also call the GetVersion() method of the PDP which returns the product version (e.g. Axiomatics Policy Server 4.0.6).

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ConsoleApplication1.DelegentPDPNoSec;

namespace com.axiomatics.sample.pep
{
    class PepC
    {
        static DelegentPDPPortTypeClient client = new DelegentPDPPortTypeClient();
        static void Main(String[] args)
        {
            client = new DelegentPDPPortTypeClient();
            GetVersion gv = new GetVersion();
            client.GetVersion(gv);
        }
    }
}

Let’s now focus on the actual authorization methods. The Axiomatics Policy Server includes a XACML 3.0 PDP which expects a XACML request and sends a XACML response back. The method we need to use to send a XACML request is InstanceAccessQuery3(…). We can simply add the line client.InstanceAccessQuery3();. However this method needs a parameter, namely the SOAP-wrapped XACML request. Let’s start from the beginning then and start creating a XACML request, bundle it inside the SOAP message and pass to our WCF SOAP client stub.

A XACML request is made of any number of attributes grouped into categories, typically the subject, resource, action, and environment categories. A request is simply the XACML representation of a plain old English question e.g. can Alice view the document? In this example:

  • Alice would be a subject identifier and belong to the subject category.
  • View would be an action identifier and belong to the action category
  • Document would be a resource type and belong to the resource category

An attribute in XACML is in fact made up of a bag of values (attributes can be multi-valued). Each value has a datatype (e.g. String, integer… Usually XML datatypes) and 1 or more values. Now, since attribute values can be any content as per the XACML 3.0 schema (see below), this means that svcutil generates classes that will require XML nodes to be built to set the value of an attribute. This is not particularly friendly and we will factor that away in a later part of this tutorial.

	&lt;xs:complexType name=&quot;AttributeValueType&quot; mixed=&quot;true&quot;&gt;
		&lt;xs:complexContent mixed=&quot;true&quot;&gt;
			&lt;xs:extension base=&quot;xacml:ExpressionType&quot;&gt;
				&lt;xs:sequence&gt;
					&lt;xs:any namespace=&quot;##any&quot; processContents=&quot;lax&quot; minOccurs=&quot;0&quot; maxOccurs=&quot;unbounded&quot;/&gt;
				&lt;/xs:sequence&gt;

				&lt;xs:attribute name=&quot;DataType&quot; type=&quot;xs:anyURI&quot; use=&quot;required&quot;/&gt;
				&lt;xs:anyAttribute namespace=&quot;##any&quot; processContents=&quot;lax&quot;/&gt;
			&lt;/xs:extension&gt;
		&lt;/xs:complexContent&gt;
	&lt;/xs:complexType&gt;

First off, let’s create the attribute that will represent the subject id Alice. We will start from creating a string that contains the value Alice. In a real scenario, this value would be read from an authentication mechanism.

            // 1. let's create a subject attribute
            String subjectId = &quot;Alice&quot;;

We now want to store that value inside an AttributeValue. To do that we must use the objects generated automatically by svcutil.

            // 2. let's store the value inside an array of XmlNode[] preparing it for the SOAP call
            XmlDocument dom = new XmlDocument();
            XmlNode node = dom.CreateNode(XmlNodeType.Text, subjectId, null);
            XmlNode[] nodes = new XmlNode[1];
            // 3. let's store the XML any nodes inside an array of attribute values
            AttributeValueType1 aValue = new AttributeValueType1();
            aValue.Any = nodes;
            aValue.DataType = &quot;http://www.w3.org/2001/XMLSchema#string&quot;;
            // we use an array below since attributes in XACML can be multi-valued
            AttributeValueType1[] values = new AttributeValueType1[] { aValue };

In the code above, note that we specify the data type of Alice. Most of the XACML datatypes are directly taken from XML itself. The list is defined in the XACML 3.0 specification. Also note we use an array of AttributeValueType1 since there can be several attribute values per attribute in XACML (the multi-valued nature of XACML attributes).
Let’s now wrap the values inside a XACML attribute (see the specification for details):

            // 4. create the containing attribute
            AttributeType1 attrContent = new AttributeType1();
            attrContent.Issuer = &quot;some issuer&quot;; // usually leave that blank
            attrContent.AttributeId = &quot;subject-id&quot;;
            attrContent.AttributeValue = values;
            attrContent.IncludeInResult = true;
            AttributeType1[] attrContents = new AttributeType1[] { attrContent };

In the above code, note the use of IncludeInResult. This relates to the ability of a PDP to return the attributes initially sent in the request along with the decision. This is useful when using the Multiple Decision Profile. Also note that attributes can have an issuer. This is used in the matching process of the evaluation of a XACML request against a XACML policy.
Now that we have attributes and their values, in this case subject-id and Alice, we can group them (it) inside a given category. This is what the code hereafter does.

            // 5. create the category containing the attr and return
            AttributesType subjectAttr = new AttributesType();
            subjectAttr.Category = &quot;urn:oasis:names:tc:xacml:1.0:subject-category:access-subject&quot;;
            subjectAttr.Attribute = attrContents;
            // repeat the code above for any attribute e.g. actionAttr, resourceAttr...

Category identifiers are defined in the XACML 3.0 specification(section 10.2.6). In this case we use the subject category identifier, urn:oasis:names:tc:xacml:1.0:subject-category:access-subject.
We can now group together our different categories into an array of categories as below. We then build a XACML request from which we derive a SOAP request (merely the wrapping of the XACML request inside a SOAP message).

            // 6. bundle the attributes inside the set of attributes for the XACML request
            AttributesType[] attrs = new AttributesType[] { subjectAttr, actionAttr, resourceAttr };
            // 7. build the XACML request
            RequestType1 xacmlRequest = new RequestType1();
            xacmlRequest.Attributes = attrs;
            InstanceAccessQuery3 soapRequest = new InstanceAccessQuery3();
            soapRequest.InstanceId = &quot;my-pdp-instance&quot;;
            soapRequest.Request = xacmlRequest;        

The InstanceId attribute in the code above refers to which PDP instance the request should be sent to. The Axiomatics Policy Server PDP has a multi-tenancy model and the PDP instance id helps identify to which particular instance the XACML request should go.

Hands on the plumbing & Handling the response

In the following code, we simply pass the XACML request to the client stub method to invoke the PDP service. Notice how the answer received can contain multiple results, each of which boasts a single decision. This, again, is due to the Multiple Decision Profile which supports sending and receiving multiple XACML requests in a single network exchange (e.g. SOAP request/response).

            // 8. send the XACML request and print the response
            InstanceAccessQuery3Response response = client.InstanceAccessQuery3(soapRequest);
            foreach(ResultType1 result in response.Response){
                Console.WriteLine(result.Decision);
            }

Refactoring the generated code

The code to create a single XACML attribute is fairly lengthy and repetitive due to the automatic code generation done with svcutil. To get around that, let’s create a small utility method which creates the right type of attribute object from the simple building blocks of an attribute: its id, value, type, and issuer.

        public static AttributesType createAttribute(String id, Uri category, String value, Uri datatype, String issuer)
        {
            // 1. create the value
            AttributeValueType1 aValue = new AttributeValueType1();
            aValue.Any = createXMLBlob(value);
            aValue.DataType = datatype.ToString();
            AttributeValueType1[] values = new AttributeValueType1[]{aValue};
            // 2. create the containing attribute
            AttributeType1 attrContent = new AttributeType1();
            attrContent.Issuer = issuer;
            attrContent.AttributeId = id;
            attrContent.AttributeValue = values;
            attrContent.IncludeInResult = true;
            AttributeType1[] attrContents = new AttributeType1[] { attrContent };
            // 3. create the category containing the attr and return
            AttributesType attr = new AttributesType();
            attr.Category = category.ToString();
            attr.Attribute = attrContents;
            return attr;
        }

.
With this small utility in hand, we can rewrite our example in a more efficient way. Below, I have included an entire simple SamplePEP class which you can use with the Axiomatics PDP.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using com.axiomatics.xacml;
using System.Xml;
using ConsoleApplication1.DelegentPDPNoSec;


namespace com.axiomatics.sample.pep
{
    class SamplePEP
    {
        static DelegentPDPPortTypeClient client = new DelegentPDPPortTypeClient();
        private InstanceAccessQuery3 soapRequest;
        private RequestType1 xacmlRequest;
        static void Main2(string[] args)
        {
            
            SamplePEP pep = new SamplePEP();
            pep.callPDP();
            
        }

        public static XmlNode[] createXMLBlob(String content)
        {
            XmlDocument dom = new XmlDocument();
            XmlNode node = dom.CreateNode(XmlNodeType.Text, content, null);
            XmlNode[] nodes = new XmlNode[1];
            return nodes;
        }

        public static AttributesType createAttribute(String id, Uri category, String value, Uri datatype, String issuer)
        {
            // 1. create the value
            AttributeValueType1 aValue = new AttributeValueType1();
            aValue.Any = createXMLBlob(value);
            aValue.DataType = datatype.ToString();
            AttributeValueType1[] values = new AttributeValueType1[]{aValue};
            // 2. create the containing attribute
            AttributeType1 attrContent = new AttributeType1();
            attrContent.Issuer = issuer;
            attrContent.AttributeId = id;
            attrContent.AttributeValue = values;
            attrContent.IncludeInResult = true;
            AttributeType1[] attrContents = new AttributeType1[] { attrContent };
            // 3. create the category containing the attr and return
            AttributesType attr = new AttributesType();
            attr.Category = category.ToString();
            attr.Attribute = attrContents;
            return attr;
        }

        public void callPDP()
        {
            // 1. collect attributes
            Console.WriteLine(&quot;// 1. create attributes&quot;);
            AttributesType subjectAttr = createAttribute(&quot;subject-id&quot;, Constants.SUBJECT_CAT, &quot;Alice&quot;, new Uri(&quot;http://www.w3.org/2001/XMLSchema#string&quot;), &quot;&quot;);
            AttributesType actionAttr = createAttribute(&quot;action-id&quot;, Constants.ACTION_CAT, &quot;view&quot;, new Uri(&quot;http://www.w3.org/2001/XMLSchema#string&quot;), &quot;&quot;);
            AttributesType resourceAttr = createAttribute(&quot;resource-id&quot;, Constants.RESOURCE_CAT, &quot;Document&quot;, new Uri(&quot;http://www.w3.org/2001/XMLSchema#string&quot;), &quot;&quot;);
            AttributesType[] attrs = new AttributesType[] { subjectAttr, actionAttr, resourceAttr };
            // 2. create XACML request
            Console.WriteLine(&quot;// 2. create XACML request&quot;);
            xacmlRequest = new RequestType1();
            xacmlRequest.Attributes = attrs;
            // 3. create wrapping SOAP request
            Console.WriteLine(&quot;// 3. create wrapping SOAP request&quot;);
            soapRequest = new InstanceAccessQuery3();
            soapRequest.InstanceId = &quot;my-pdp-instance&quot;;
            soapRequest.Request = xacmlRequest;

            try
            {
                InstanceAccessQuery3Response resp = client.InstanceAccessQuery3(soapRequest);
                ResultType1[] results = resp.Response;
                foreach (ResultType1 res in results)
                {
                    DecisionType1 decision = res.Decision;
                    Console.WriteLine(decision.ToString());
                }
            }
            catch (Exception err)
            {
                Console.WriteLine(err.Message);
            }
        }
    }
}

Enjoy!

Standard

The distance of a second

One of my side hobbies is to browse the web for nice designs and interesting ways to represent information. I really like 2 blogs in particular: Information is Beautiful and the second is Grain Edit (check out their respective web stores for neat stuff).

In addition to liking design, I also truly like techy stuff and in particular programming languages or declarative languages (by that I mean Java in the former instance and XML in the latter). SVG is a great standard to draw vectorial images using XML.

I had therefore had my first attempt at representing information in a neat way: the distance of a second (the distance an animal / human / vehicle achieves in a fixed amount of time i.e. 1/60th of a minute). And the result is below…

Distance of a second

Distance of a second

I used Inkscape to design the file. I used icons from the amazing Noun Project.