From the Desk of Oracle ACE Director

Chris Muir

Subscribe to Chris Muir: eMailAlertsEmail Alerts
Get Chris Muir: homepageHomepage mobileMobile rssRSS facebookFacebook twitterTwitter linkedinLinkedIn


Related Topics: Java EE Journal, Java Developer Magazine

Blog Feed Post

ADF Security Revisited (Again Again)

What I find difficult with the JDev 11g Fusion Guide is the raw depth of information to read and assimilate

This is a revisit of the ADF Security features under JDeveloper 11g and subsequent deployment to WLS. There are plenty of good examples and documentation on this feature and readers are encouraged to seek those out. This post is my cut of implementing ADF Security to make sure I've all the moving pieces clearly defined in my head. As usual I thought this post may be of interest to readers.

Assumptions
Readers understand the security concepts of authentication and authorization, and readers are familiar with the WLS security "myrealm" concept.

Sample Application
What I find difficult with the JDev 11g Fusion Guide is the raw depth of information to read and assimilate around the security space. Section 29 has 80 odd pages on security which is a lot to digest. Without a doubt security is an important topic but trying to understand the full 80 pages leaves me wiped out.

To make the discussion on ADF Security easier, let's discuss an extremely simple application and then describe what we're attempting to achieve in terms of security.

Consider the following application:


... and the following page flow:


The diagram reveals the following points about our application:

1) The Splash page is a landing page for our application where new unauthenticated sessions will land as they access the application for the first time. This page will be a simple web page with no ADF Bindings. It will provide links to the other 3 pages.

2) ViewBookings, a page showing data using ADF Bindings, will be a secured page. Only authenticated users will be able to access the page and they must have the ADMIN role.

3) ViewEvents, another databound ADF page using ADF Bindings, will also be a secured page. Only authenticated users will be able to access the page, but there are no role restrictions on the page, giving any authenticated user the right to access the page.

4) ViewOrganisations, another databound ADF page using ADF Bindings, will not be secured. Therefore authenticated and non-authenticated users will be able to access the page, and implicitly via this, there are no role restrictions on the page.

(You'll note in the above points I've been careful to identify databound pages that have ADF Bindings (ie. ViewBookings) and those that don't (ie. Splash). The ADF Security mechanisms *only* work for pages that have ADF Bindings and the relating pagedef files. A page that doesn't have ADF Bindings is not secured. This implies how we treat the unbound Splash page vs the bound ViewOrganisations page is different. The mechanisms for this will become apparent further in this post.)

Best practice side note: as a general recommendation while this article demonstrates a page that is totally unsecured via the ADF Bindings mechanism, readers should give strong consideration to create PageDef files for all pages regardless if they are databound or not. This is done by selecting the Page Definitions option from the page's context menu, then allocating them the anonymous-role making them accessible to anyone as explained later in this article. Implementing this gives you a number of advantages:

a) Improved control of the public page's content, displaying different content for authenticated vs unauthenticated users
b) A consistent security implementation across all pages
c) Easier to audit the security implementation

In order to support our application as described in the points above, we'll need a number of security "parts" for our application. Following is a summary of those parts, of which we'll describe in detail next in this document

1) A login page to authenticate users
2) An application role called ADMIN
3) An application role that identifies authenticated users
4) An application role that identifies a user regardless if they're authenticated or not
5) The ability to secure the ViewBookings page for users with the ADMIN role
6) The ability to secure the ViewEvents page for users who are authenticated
7) A mechanism to create users, create roles and assign users roles

Luckily JDeveloper provides a number of features to make this easy.

We'll add one other further security requirement. Though our application will internally make use of a role named ADMIN, once deployed to our application server the role will be called ADMINISTRATOR. As such our additional requirement is:

8) Map the application role ADMIN to the enterprise role ADMINISTRATOR.

A final point before continuing, in order to keep this example simple I've steered away from the ADF Task Flow features of JDev 11g, specifically bounded task flows. In this simple example I've stuck to the default single unbounded task flow with separate pages in order to aid understanding. In reality both task flows and pages are treated in a similar fashion so what you learn here will apply to both.

Configure ADF Security
The ADF Security wizard implements a number of the security features we require. For our open application selecting the Application menu -> Secure -> Configure ADF Security option invokes the Configure ADF Security wizard. This wizard has been described in a number of other documents and examples, so I'll not talk through all it's options, but rather just show the options picked for our example.

In step 1 of 5 we pick the ADF Authentication and Authorization option:


Step 2 of 5 we'll get JDev to create a login and error login page for us, such that the user will see an in-page login page in our application to authenticate themselves:


Step 3 of 5 we'll ask JDev to blanket grant privileges to our existing pages. We'll tidy this up in a later step. Typically we wouldn't use this option but rather the "No Automatic Grants". No grants forces developers to explicitly think about each page and what privileges to define. For demonstration purposes we're showing the other option:


Step 4 of 5 we'll leave the "Redirect" option unselected. When selected this option provides the ability to have all authenticated users redirected to a standard landing page:


Step 5 of 5 tells you what changes JDev will make on your behalf to implement the features. This screen is useful as it gives you a good understanding of what configurations are required to make ADF Security work.


Once completed the most important JDeveloper screen from here for configuring security in your application is the jazn-data.xml editor. It's accessible by opening the file under Application Resources -> Descriptors -> META-INF -> jazn-data.xml, or the Application menu -> Secure -> ADF Policies. Ensure the Overview tab at the bottom of the editor is selected. On first opening the jazn-data.xml file you'll see:


As our application includes no bounded task flows, just web pages, select the Web Pages tab at the top of the editor. For our specific application it reveals:


From here you can see three of our four pages. As the Splash screen has no ADF Bindings, it does not display and therefore has no options for defining grants and priviliges. This is because as we mentioned early in the post, only databound pages are secured by ADF Security. If we alternatively select one of our databound pages we see:


In this case the ViewBookings databound page has the role "test-all" with "View" access granted to it. In a similar fashion ViewEvents and ViewOrganisations will have the same mappings. The role "test-all" and blanket assignments to each page was generated by step 3 of the Configure ADF Security wizard.

At this stage, of our initial 8 security requirements, we've implemented #1 only. Obviously the last few steps have set up a lot of internal infrastructure and configuration for us behind the scenes which assist the next sections of work.

Application Roles vs Enterprise Roles
Our application has the security requirement to create a role called ADMIN and secure the ViewBookings page with that role. In JDeveloper security "speak" this sort of role is referred to as an *Application Role*, effectively a role that the application defines and wants to enforce against certain resources, namely web pages and task flows in our ADF application. At deployment time this role is essentially private to the application.

Application Roles are distinctly different from Enterprise Roles as they have a finer level of granularity, they only apply to one application. Conversely Enterprise Roles map to user groups within an organisation and can apply across applications, though they allow the flexibility of a 1 to 1 mapping with Application Roles too.

Another way to categorize the difference between Application Roles and Enterprise Roles is where they're implemented. Application Roles are implemented in the application at hand, while Enterprise Roles are configured in our application server or higher level identity management systems such as LDAP, MS Active Directory, OID and more.

This distinction becomes important as we configure our Application Roles, as we need to define both the Application Role, the Enterprise Role, and the mappings between them. If we don't do this, when the application is deployed, and a user accesses the system with the Enterprise Role ADMINISTRATOR, the application server has no way of knowing that this maps to the application's ADMIN role.

As per the previous section the JDeveloper security wizard predefines an Application Role named "test-all" for us. From the jazn-data.xml editor this is evident on the existing grants to pages and task flows. The intention is for development and testing purposes, any user granted the test-all role has unlimited access to the application. For a production environment this role is not suitable as it is granted to all anonymous users; any user accessing the application is already a member of this role allowing unrestricted access.

To see where the Applications Roles are defined select the User and Roles tab on the bottom of the jazn-data.xml page, followed by the Application Roles node on the left hand side:. This will display the Edit JPS Identity & Policy Store dialog:


You'll note you can see the "test-all" role defined under the Application Roles node. In our case we'll add a new ADMIN role, and remove the "test-all" role as follows:


From here we want to map the Application Role to the Enterprise Role. Remember again that Enterprise Roles exist within our application server, while the Application Role is defined within our application.

We now move to creating the ADMINISTRATOR Enterprise Role under the same left node menu option:


Next we need to map the Enterprise Role to the Application Role. With the ADMINISTRATOR Enterprise Role selected, select the Assigned Roles tab on the right, followed by the plus sign and the Assign Application Role option. In the resulting Select Roles dialog select the ADMIN Application Role. The result:


Protecting our pages with Application Roles

On completing the previous steps, on returning to the ADF Policies tab followed by the Web Pages tab, we'll note that because we removed the test-all role, none of the databound pages have roles assigned to them (identified by the fact they no longer have arrows to the right of them):


To allow users with the ADMIN Application Role to access the ViewBookings page, we simply select the page, the plus button allows us to pick the ADMIN role from the appropriate dialog, and finally we select the View option on the right hand side:


The 4 other privileges, Customize, Edit, Grant and Personalize are relevant to MDS and not applicable to this post. As such the remaining View privilege tells us ADF Security via the jazn-data.xml file is at it's most basic determining if a user can access the page or not. It's not concerned with any other privileges.

Read the original blog entry...

More Stories By Chris Muir

Chris Muir, an Oracle ACE Director, senior developer and trainer, and frequent blogger at http://one-size-doesnt-fit-all.blogspot.com, has been hacking away as an Oracle consultant with Australia's SAGE Computing Services for too many years. Taking a pragmatic approach to all things Oracle, Chris has more recently earned battle scars with JDeveloper, Apex, OID and web services, and has some very old war-wounds from a dark and dim past with Forms, Reports and even Designer 100% generation. He is a frequent presenter and contributor to the local Australian Oracle User Group scene, as well as a contributor to international user group magazines such as the IOUG and UKOUG.