Thursday, November 3, 2011

ADF Security Basics

ADF security is a pretty deep topic especially when you put it in perspective of an enterprise deployment and how the security infrastructure works together with the application server to provide for the functionality. Also, there are a number of great resources out there that give a good understanding about how to configure and secure an ADF application. My first go-to resources on the web would be :

Oracle ADF Documentation : Section 35
Chris Muir's Blog Post

Having said that, this is a quick look at the various aspects included in ADF Security  and a rundown of whats possible with ADF security and how to implement some fairly common use cases.  The example is based on the HR schema and can be downloaded from here.

In its simplest form, ADF security is declarative and protects pageDef files( for pages in the Unbounded taskflow) and whole BTFs (Bounded Taskflows), it can also be applied to EOs and EO attributes, which I personally consider especially powerful when combined with Oracle Database's VPD feature ( maybe that's a good topic for a blog post ! ).

ADF security is based on OPSS which in turn is based on JAAS. In this model, we create "application roles" and grant permissions to application roles to do certain operations within the application and hence the name. So the ability to do a set of operations is collected and called a role. Now these roles are granted to specific users, which enable those users to do all the actions defined by those roles assigned to them. In a real production environment however, the users are not defined in the context of a single application, instead they would be defined for the whole enterprise and granted access to various applications, all using the same user name (a single sign-on or SSO). So these identities (or users) would be defined in an identity store like LDAP and WLS can work with such systems. In WLS we can create "enterprise roles" which is very similar to application roles, but are defined at the container (app server) level, and so all applications can use them. Therefore, in a production setup, we also have to map application roles to enterprise roles (for each application) and then associate users to the enterprise roles. This makes it possible for developers to develop applications without worrying about enterprise roles or application roles used by other teams and products.

By default when we enable ADF security , the bounded taskflows and the pagedefs for the pages in the unbounded taskflows are secured. The UBTF is not security aware and cannot be secured as a whole like the BTFs. Entity objects and EO attributes are not secured by default, and requires a grant to be given explicitly.

Tip :  to secure a page that does not use the ADF bindings, we can just create an empty pageDef file by right-clicking the page and choosing "Go to PageDef" . This empty pageDef can then be used to secure the page.

EO (and therefore editable VOs) can also be secured on the basis of application roles. Security is applied on two levels for an EO. On the EO as a whole or on a specific property of the EO. For the whole EO, security permissions exist to restrict read,update and delete on the EO. For EO attributes the permission exists to secure the update operation on any field. Column-wise security can be done on the View layer by toggling the visibility of a table column based on a security EL.

More Details & Example Application

The example application tries to demonstrate various use cases and how to secure various parts and pages in an application.The example is built on the standard HR schema and has two bounded task flows apart from the default unbounded task flow. The example has a landing page, and a taskflow to maintain (Search & Edit) Employees and another taskflow to maintain Departments.

For the example, we shall define the following Application roles in our application :

  • EmployeeAccess - can view MaintainEmployees taskflow
  • DepartmentAccess - can view MainatinDepartments taskflow
  • EmpManager - can edit employee details (except salary)
  • DeptManager - can edit department details
  • SalaryManager - can edit salary for employees
 For the purpose of demonstrating various cases, the task flow is structured as below :

The Landing Page
 The landing page, Welcome.jspx,  is accessible for everyone, but also contains an embedded taskflow that is displayed only to authenticated users who have access to view it. There are links on the welcome page that take the user to other pages and require the user to authenticate before the page is displayed to them. The other pages to search for and edit employees and departments, require the user to have various access levels to perform various actions.Welcome.jspx is a publicly accessible page. It is made public by granting 'view' access on this page, to the 'anonymous-role' built in role. To do this, open your jazn-data.xml and follow the steps below :

The jazn-data.xml editor allows you to associate roles to pages/taskflows

The same dialog is used to set permissions for taskflows (change dropdown marked "1" from webpage to Taskflow). The roles defined will be shown in area marked "3".

In the UI pages we can use the security EL to show hide fields or to make then editable and non editable. If you open the expression builder you will see the securityContext object in the bindings object with a number of very useful methods in it.
Notice the expression to check if the user has permission to view a taskflow, and also the various methods exposed by the securityContext object(click to enlarge)

On the welcome page the following EL is used to render the bounded taskflow as a region

This EL basically checks if the logged in user has access to see the taslflow. The taskflow is referenced by giving the path to the taskflow xml file (relative to the WEB-INF directory) followed by the taskflow name.

At this point its worthwhile to note that permissions are usually hierarchical in nature. The role that can edit the salary for an employee would surely have the permissions to edit and view employees. So in our case the permissions would be like this :
Hierarchical Permissions

The Maintain Departments Page
The MainatainDepartments page and taskflow are secured and is available to authenticated users who have the DepartmentAccess permission or above (see the permission hierarchy above ). With the DepartmentAccess permission the users can search departments and view details, but cannot edit anything, because we will ensure that components are editable only based on the permissions granted to the logged-in user. To edit a department, the user needs the DeptManager  permission. This taskflow is also calledby the edit employee taskflow where an employee who has the permission to edit departments can directly edit a department.
The Maintain Departments BTF supports parameters to directly show the edit page for a given department.
The Maintain Employees page
The Maintain Employees page and taskflow are also secured and accessible to people with appropriate permissions. Just like Departments, the user needs an EmployeeAccess  permission to view , and an EmpManager permission to edit details. But in this case, we implement EO level security, by requiring the some users to also have a SalaryManager permission to edit a user's salary. The  permission hierarchy screenshot above should make better sense now. SalaryManager gets to everything, the next lower permission, EmpManager gets to edit everything but the salary, and the lowest permission EmpAccess allows only readonly access The taskflow diagram is below :

The Mainatain Employees BTF is simple and has a taskflow call to directly edit Departments.
The EO level security for the salary is set by selecting the EO attribute to enable security on it.
Enabling security on EO attributes.
Once security is enabled, you need to associate roles to it, or no one will be able to edit this attribute.
This is a little tricky just because the JDeveloper menu is very well hidden !
To associate the roles do this :
Select the EO in the navigator window

Right click the EO attribute in the structure window to get the "Edit Authorization" Menu
This opens up the following dialog :

In this dialog, the application roles are displayed and you can grant the permission to the roles you select.

Showing/Hiding UI elements based on permissions
 Since we mostly use EL to check for permissions and decide whether or not to display some attribute, or set the readOnly property, having this hierarchical form is very beneficial as you see below. The code below is for the first column in the result table on the employee search. This column will render a link which can be clicked to view the employee details and edit them for an 'EmpManager' role, but will render as read only text for people with 'EmployeeAccess'. Now from the hierarchy we have, there is another level above 'EmpManager' and that is 'SalaryManger'. This higher level also needs to be able to edit employee information because by definition, the 'Salary Manager' can do whatever the roles below it can do, plus something extra (edit salary, EO level security in this case). So the EL securityContext.userInRole[''] will return true for and any if its parent roles. So in this case, when a user with the role 'SalaryManager' logs in he sees the link and not the readonly text becasue the expression will return true since 'SalaryManager' is a parent role of 'EmpManager'.

See the highligted EL expressions to see how application roles are referenced

That all the basics. What we have not looked at here is the integration with the WLS security infrastructure and Identity & Access Management tools like LDAP, OID and OAM.

You can download the source code here :
To run the project, you can run the Welcome.jspx page. You will notice that some Authorization exceptions are not handled. These were left to demonstrate what happens when an authenticated user tries to access a page he is not authorized for. The exceptions can be handled by exception activities in the task flow , or the navigation links can be shows or hidden based on the authorization of a user.

By default the following users are configured (see jazn-data.xml to view/change these) :
User                  Password                   Role
department        weblogic123              DepartmentAccess
Dmanager         weblogic123              DeptManager
employee          weblogic123              EmployeeAccess
Emanager         weblogic123              EmpManager
empdept           weblogic123              DepartmentAccess & EmployeeAccess
Smanager         weblogic123              SalaryManager