Quickly (temporarily) disabling role based authorization in JHeadstart Applications

Implementing role based authorization, linked either to JAAS or your home grown authentication and authorization approach, is pretty simple using JHeadstart. All it takes is configuring the JhsAuthorizationProxy bean as JhsUserRoles (by checking a checkbox in the Service element of the Application Definition file) and you are set.

JAAS based authentication and authorization protects resources such as pages – by specifying security constraints in the web.xml file. JHeadstart adds much more refined authorization that allows us to enable/disable and show/hide elements, such as menu-options, buttons for Data Manipulation, input-fields etc. based on the role a user has. On a Group level we can specify the roles that have access – that results in menu options being visible to users that have one of the specified roles. Furthermore, we can use expressions such as #{jhsUserRoles[‘admin,manager’]} for properties such as disabled, updateable, display in form layout & display in table layout, Insert/Update/Delete allowed. This expression evaluates to true if the current user has one of the roles mentioned in the comma separated list.

So in short, these authorization facilities are hunky dory. So whence this blog? Well, after having implemented role based authorization we have effectively shut ourselves out of our own application, unless of course we have the proper role privileges. For development purposes, it can be very convenient to (temporarily) switch off roles based authorization – to have the application fully functional without the burden of authorization.

This article describes a simple method for easily disabling (and enabling again) the role based authorization mechanism in JHeadstart.

 

Disabling basic JAAS authorization is the first step we have to take. That is an easy one: simply open the web.xml file and change the file extensions in the

Quickly (temporarily) disabling role based authorization in JHeadstart Applications disableAuth

URL-pattern in the web-resource-collection element in the security-constraint(s). This tells the application server to protect resources whose url ends with jspxX (and they probably do not exist) rather than jspx.

The second step is JHeadstart specific. The JhsUserRoles managed bean is an instance of the JhsAuthorizationProxy Class. Expressions such as #{jhsUserRoles[‘admin’]} are evaluated by calling the get object on this class, that implements the Map interface. Disabling role based authorization means that these expressions should always evaluate to true, regardless of the actual roles a user has. That means that in disabled mode, the get() method on the jhsUserRoles bean should return true.

In order to implement this behavior, I have created a subclass of the JhsAuthorizationProxy class, that specifies a (to be managed) property useRoleAuthorization and overrides the get method. This class looks like this:

package nl.amis.jheadstart.controller;

import oracle.jheadstart.controller.jsf.JhsAuthorizationProxy;

public class AMISJHeadstartAuthorizationProxy extends JhsAuthorizationProxy {
    public AMISJHeadstartAuthorizationProxy() {
    }

    private boolean useRoleAuthorization = true;

    public Object get(Object key)
    {
      // If useRoleAuthorization is false, the application is running in 
      // NO ROLE BASED AUTHORIZATION mode, and we always return true.
      if (!usesAuthentication())
      {
        return !useRoleAuthorization;
      }
      else 
      {  
        return ((!useRoleAuthorization) || ((Boolean)super.get(key)));
      }
    }

    public void setUseRoleAuthorization(boolean useRoleAuthorization) {
        this.useRoleAuthorization = useRoleAuthorization;
    }

    public boolean isUseRoleAuthorization() {
        return useRoleAuthorization;
    }
}

The bean configuration entry in the faces-config.xml file for this bean is like this:

    <managed-bean>
    <managed-bean-name>jhsUserRoles</managed-bean-name>
    <managed-bean-class>nl.amis.jheadstart.controller.AMISJHeadstartAuthorizationProxy</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
    <managed-property>
      <property-name>useRoleAuthorization</property-name>
      <value>true</value>
    </managed-property>
  </managed-bean>

By changing the value of managed property from true to false we can switch of the role-based authorization.

It is also possible to build this facility – again, only for development purposes – into the application itself, to allow users to click on a button in order to switch on or off the roles based authorization.