When OpenID meets XACML: externalize authentication and authorization from your business apps
About a year ago, a few months into my new job at Axiomatics, I pulled together a web-based app using J2EE (JSF, servlets, POJOs) and Icefaces (AJAXfied JSF) to illustrate fine-grained access control for web applications and portals.
To secure the application, I used Tomcat’s authentication mechanism (its implementation of the HTTP FORM-based authentication protocol) and Axiomatics‘s off-the-shelf Authorization filter for servlets.
What I then got – at zero development effort – was a sturdy, secure, finely-grained controlled web app where users could access certain pages and/or parts of pages based on the set of attributes a given user had potentially combined with attributes of the targeted resource (the page, the portlet, the individual GUI element of the page…), the action the user wanted to run (HTTP GET? HTTP POST?), and possibly environment values (time, encryption type?). We were pretty much cruising down XACML Lane, picking all the benefits of Attribute-Based Access Control.
Out goes FORM-based AuthN, in comes Open ID
However, I was not really satisfied with the authentication side of things. I had gone for the easy path – to use Tomcat’s native tool (a list of users inside a configuration file called tomcat-users.xml) which I had extended to include other user attributes. But it didn’t seem overly realistic in an enterprise scenario. I had thought of using LDAP but had never found the time to configure Tomcat to use LDAP instead.
That’s when I bumped into Travis Spencer of Ping Identity. A few weeks ago, Travis came over for a visit in our Stockholm offices. Then and there, Travis introduced me to Ping’s capabilities in terms of (a) externalizing authentication and (2) bridging between different authentication sources and protocols. I wasn’t restricted to Tomcat’s FORM-based authentication anymore. I could choose from a plethora of identity providers, typically OpenID-based providers such as Google or Yahoo, but also Facebook Connect.
The source of authentication and the ease of integration are not the only winning factors here. Considering XACML – in the authorization phase – uses attributes extensively, one of the key points is to be able to retrieve such attributes. And that’s where OpenID, SAML, and Ping come into play. It is indeed possible to authenticate with an IDP and retrieve attributes about the user the IDP might be maintaining.
The best of both worlds: achieving externalized authentication & authorization
With that in mind, Travis and I drew up a plan for a new demo integrating Ping Identity’s Ping Federate and Axiomatics’s Policy Server. Travis also describes the architecture on his blog.
In addition to inserting the Axiomatics Servlet Authorization Filter, I now added an Authentication filter responsible for redirecting users to the authentication form of their favorite IDP e.g. Google via Ping Federate. From my app’s perspective, and in particular the filter’s perspective, that amounted to an HTTP 302 redirect to Ping Federate which in turn redirected to the relevant IDP. What’s interesting to note is that PF might talk different protocols with different providers but ultimately always returns the same pre-agreed token format to the authentication filter. In our case, we opted for an encrypted cookie which contained additional attributes about the user.
The authentication filter can then decrypt the token, extract the attributes, create a user session, and add those attributes to the session. Next comes the Authorization filter which can read those attributes from the session and use them to build a XACML request to be sent to the APS. It can also add contextual attributes such as the time of the request. Lastly, it is capable of extracting additional information from the HTTPServletRequest object itself, typically the targeted URI and the HTTP method (GET? POST?)
Based on the attributes it is given, the APS can then reach different decisions (either Permit or Deny). In this demonstrator, we opted for a resource-centric access control model where we defined different policies grouped together in a policy set. Each policy focuses on a separate resource (or web page as is the case here). Policies can contain rules which can focus on finer-grained aspects of the resource e.g. a GUI element (a button? a menu item?). Lastly, because multiple sources of authentication are potentially used, it is possible for APS to reach decisions based on the origin of the user token. Administrators can then author access control policies of the like:
Only allow users that have authenticated with Google.
Richer business flows with XACML obligations
One of the neat features XACML offers is the use of obligations. Obligations are statements that a PDP can return to a PEP along with a decision e.g.
Yes Permit, provided the PEP logs the fact the user has requested this resource in the corporate logging system.
In this demo, obligations are particularly handy. We chose to implement a banking scenario where certain pages require different levels of authentication (from none to OpenID to internal enterprise authentication). Should a user authenticated with Google try to access a page which requires stronger authentication, the PDP can deny access and ask the PEP to redirect the user to a page where the user will have the option to either log in using an enterprise account or create a new account.
This sort of scenario is recurrent with our banking customers: imagine a retail bank webapp where users authenticate using their normal credentials (e.g. username/password). The bank lets them view their balance. However, for more advanced functions e.g. money transfers, the bank requires stronger authentication. XACML obligations can implement this type of flow very naturally.
A sneak peek at the demo
This short video demo illustrates the use of Ping Federate with Google OpenID and Axiomatics Policy Server.