Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Secure Java REST APIs With JSON XACML and ALFA

DZone's Guide to

Secure Java REST APIs With JSON XACML and ALFA

how to use a JSON XACML Policy Enforcement Point to secure REST API endpoints using ALFA, XACML, and JSON.

· Security Zone ·
Free Resource

Discover how to provide active runtime protection for your web applications from known and unknown vulnerabilities including Remote Code Execution Attacks.

In this post, we’ll look at how to use a JSON XACML Policy Enforcement Point to secure REST API endpoints. We will use ALFA, XACML, and JSON to do so.

Setting the Scene

Let’s imagine we have a REST API that helps us manage purchase orders. The API provides users with the ability to view, edit, approve, and delete purchase orders.

Business Data

In this simple example, we will have data about employees and data about purchase orders. The simplified ER diagram looks like the following.

The API

We will expose the following functionality via the API.

HTTP Verb

Entire Collection (/purchaseorders)

Specific purchase order (e.g. /purchaseorders/{id})

POST

201 (Created), 'Location' header with link to /purchaseorders/{id} containing new ID.

404 (Not Found), 409 (Conflict) if resource already exists..

GET

200 (OK), list of purchase orders.

200 (OK), single customer. 404 (Not Found), if ID not found or invalid.

PUT

405 (Method Not Allowed).

200 (OK) or 204 (No Content). 404 (Not Found), if ID not found or invalid.

DELETE

405 (Method Not Allowed)

200 (OK). 404 (Not Found), if ID not found or invalid.


The API can be implemented using any language you like, e.g. .NET, Java, or other.

Defining Authorization Requirements

Given the limited set of data in this sample use case, here are some authorization requirement examples:

  • A manager in the purchasing department can create a new purchase order
  • A manager in the finance department can view purchase orders in their regions.
  • A manager in the finance department can approve a purchase order in their region if the PO amount is less than the user’s approval amount.
  • No one can view the credit card number associated with a purchase order.

Authorization requirements are defined separately based on the business analysts’ user stories. They are decoupled from the application/REST API so that:

  1. They can evolve independently of the API codebase.
  2. They can be expressed as policies and provide more transparency into the authorization.

Implementing the Requirements Using ALFA

ALFA is a lightweight syntax that lets you write authorization policies extremely easily, reducing the friction of writing policies in XACML, and also reaping the benefits of using this standardized language, all while expressing relationships and graphs. Axiomatics donated the syntax definition to OASIS as a candidate profile. Axiomatics also provides, free of charge for non-production usage, an Eclipse plugin to edit policies written in ALFA as well as a command-line tool to compile ALFA into standard XACML.

namespace axiomatics {
    /**
    * No one can view the credit card number
    * associated with a purchase order.
    *
    */
    policyset purchaseorder {
        target clause objectType == "purchase order"
        apply firstApplicable
        /**
        * View...
        */
        policyset viewPO {
            target clause actionId == "view"
            apply firstApplicable
            policy managers {
                target clause role == "manager"
                and department == "finance"
                apply firstApplicable
                /**
                * A manager in the finance department
                * can view purchase orders in their regions
                */
                rule allowSameRegion {
                    permit
                    condition user.region == po.region
                }
            }
        }
        /**
        * Create...
        */
        policy createPO {
            target clause actionId == "create"
            apply firstApplicable
            /**
            * A manager in the purchasing department
            * can create a new purchase order.
            */
            rule managersCanCreate {
                target clause role == "manager"
                and department == "purchasing"
                permit
            }
        }
        /**
        * Approve...
        */
        policyset approvePO {
            target clause actionId == "approve"
            apply firstApplicable
            /**
            * Managers in finance
            */
            policy managers {
                target clause role == "manager"
                and department == "finance"
                apply firstApplicable
                /**
                * A manager in the finance department
                * can approve a purchase order in their region
                * if the PO amount is less than the approval amount.
                */
                rule approveUptoLimit {
                    permit
                    condition po.amount <= user.approvalLimit
                }
            }
        }
    }
}


Defining a REST Policy Enforcement Point (PEP)

Let’s assume we are implementing the REST API using Java and JAX-RS. The same principle will apply to other technologies.

Intercepting at the Right Layer

We need to implement a PEP that is capable of inspecting the request (and optionally inspecting or manipulating the response). Given JAX-RS services build on top of Java Servlets, we could write a Servlet filter. However, such a filter would not give us access to the structured information. Rather, JAX-RS comes with interceptors, which is a type of plug-in that gives a developer access to a structured message body (JSON or XML) as it is being read or written.

There are two kinds of interceptors, ReaderInterceptor and WriterInterceptor. Reader interceptors are applied to inbound entity streams. A reader interceptor lets you manipulate the request entity stream. Writer interceptors let you manipulate the response e.g. to redact or mask data. For instance, the fourth requirement (No one can view the credit card number associated with a purchase order) would be implemented by altering the response.

Sending the Right Authorization Request

Use the ReaderInterceptor to parse the incoming message and generate the relevant authorization request. Think about elevating the request i.e. crafting an authorization request that is meaningful from a business point-of-view rather than a request that is technical. For instance use view, edit, delete rather than POST or GET.

Use the JSON Profile of XACML to generate your XACML request as it is more lightweight and simpler than XML.

Enforcing on the Way In and Out

As previously mentioned, use the WriterInterceptor to manipulate the response and redact part of the response.

Tying it All Together

Once your enforcement point is written, you can deploy it to your REST API and start applying fine-grained, relationship-based authorization. Do not forget to deploy your authorization policies.

Find out how Waratek’s award-winning application security platform can improve the security of your new and legacy applications and platforms with no false positives, code changes or slowing your application.

Topics:
java rest api ,json ,xacml ,data security ,business database ,access control ,oasis ,rest api security ,integration ,tutorial

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}