An essential non-functional requirement of any system is security. Different categories of users are allowed to perform different functions, and these requirements are satisfied by the two-pronged approach of authentication and authorisation. Authentication is pretty well covered by existing frameworks while authorisation is feasible but less elegant. How can this be improved?
First, a quick recap.
Authentication is the process of proving that you have the right to assume an identity (that has been previously set up in some kind of registration process) when using a web site. Authentication processes vary, the most typical being the process of logging in with a username or email address (usually public or semi-public information) and a password (known only to the individual user). For security purposes the authentication process should take place over a secure (HTTPS) connection; this prevents somebody intercepting traffic between the user and the web site and obtaining the user’s authentication details.
Authorisation is the process of ensuring that a user can only perform those actions that they are allowed to. In simple terms a user is usually given one or more roles; each role permits access to one or more functions within the site. The underlying software ensures that both authentication and authorisation checks are enforced where applicable, allowing users to perform the activities that they are authorised to perform and preventing users from performing activities that they are not authorised to perform.
Take as an example a simple forum site – not just anybody can post a message, approve new accounts, or take down inappropriate messages. The security requirements for such a site are pretty typical – users must be known to the site to be able to post messages, and a sub-set of the site’s functionality to do with administration must only be available to those users who have been assigned an administration role.
Both authentication and authorisation are well supported by Java Enterprise Edition. Authentication can be applied to URLs, ensuring that users cannot access areas of the web site unless they have sucessfully authenticated. Authorisation can be applied to EJB methods using deployment configuration or annotations, ensuring that only users with one of the relevant roles can execute those methods. However there are aspects of authorisation where JEE leaves something to be desired.
Although authentication and authorisation can be applied declaratively to URLs, authorisation based on data (request parameters, POST values) is not supported. And while authorisation-based protection is also supported for EJB method calls there is no declarative support for authorisation based on the data being manipulated.
The common approach to solving this problem is to use declarative security to enforce roles (what I will refer to as the ‘has role’ check), whilst using programmatic security to enforce property-based constraints (the ‘role scope’ check) – a snippet of code at the start of a method or in an aspect performs the requisite security checks.
The problem with this approach is that it is susceptible to error. Security systems should default to being fail-safe – if a method has no security applied to it, then it should not be accessible to anybody. The traditional approach to the ‘role scope’ check breaks this rule, and require attention to detail by the developer to ensure that the right security is implemented, and comprehensive code reviews to double-check. Such checks cannot easily be automated.
In an ideal world it would be possible to use declarative security to cover both the ‘has role’ and ‘role scope’ checks; this blog post outlines such a solution, based on the use of annotations and aspect oriented programming.
Annotations
Annotations are already used to provide a declarative approach to the ‘has role’ check; it is possible to extend this to cover both the ‘has role’ and ‘role scope’ checks using a single annotation. Using annotations means that the roles and role scope can be expressed for each method in a clear and consistent manner alongside the method being secured.
Aspect Oriented Programming (AOP)
AOP is already used in a number of security solutions and can be used to examine the annotations attached to a method and perform processing based on those annotations.
Architectural Approach
To simplify the application of authorisation checks the architectural approach would be to present a clean and unified business process API, referred to as the orchestration layer, to the presentation tier. A single point of back end authentication and authorisation enforcement simplifies implementation and makes it easier to ensure that all methods have security enforced – for example, with fail-safe AOP code that fails if no annotation is present on a method.
Once this orchestration layer security has been implemented it will then be possible to turn our attention to the presentation tier. Here there are several overlapping requirements. First and foremost, users should not be able to navigate to a page that their role does not permit them to view. Secondly the site should not render links on pages that the user can view, to pages that they cannot navigate to. Finally, in both of these scenarios the data that the user will see must also be taken into account – so that a user can visit an ‘edit’ page for their own data but not for data belonging to another user.