TECHNOLOGY: Oracle ADF
Security for EveryoneBy Frank Nimphius
Protect your Oracle ADF applications from unauthorized access using the Oracle ADF Security feature.
Historically, Java EE developers have used container-managed security and Java Authentication and Authorization Service (JAAS) to implement security in their applications. For implementing security in Oracle Application Development Framework (Oracle ADF) and Oracle Fusion Middleware applications, however, Oracle provides Oracle platform security services, an integrated security environment that builds on the underlying Java EE standards and is portable across application servers.
The Oracle ADF Security feature provides a declarative and visual development environment for building Oracle platform security services-based security into Oracle ADF applications. Together, Oracle ADF Security and Oracle platform security services enable developers to focus more on what needs to be protected than on how it should be protected.
This article introduces Oracle ADF Security and shows how developers can use it to implement security within their enterprise Oracle ADF applications.
Introducing Oracle ADF Security and Oracle Platform Security Services
Three key concepts are critical in understanding Oracle ADF Security and Oracle platform security services: user identities, enterprise roles, and application roles.
User identities define users in an enterprise. Users—such as company employees—usually have a single username/password pair they use to authenticate themselves to applications within an organization. A user identity defines only who the user is—it does not define any access privileges.
To ease system deployment, administrators often organize users into enterprise roles, which provide a way to manage groups of users who have similar requirements when accessing enterprise resources. For example, employees may all be grouped into an enterprise role called Employees to give them access to all employee self-service applications within an enterprise. From an administrative point of view, it is easier to add users to or remove them from an enterprise role than to maintain individual user grants for an application.
Application roles are specific to an application and are used to grant privileges to users defined in enterprise roles. Application roles make it possible for all users who belong to an enterprise role (such as Employees) to have specific access privileges defined for various applications. For users within an enterprise role to work within an application, application roles must be granted to the enterprise role. Application roles can be granted directly to users, but this practice is rare and is not considered good programming design.
Figure 1 shows the Oracle platform security services architecture, both at design time in Oracle JDeveloper and at runtime in Oracle WebLogic Server. At design time, user identities, enterprise roles, and security policies are defined in a local file called jazn-data.xml. It is located in the src\META-INF directory of the application root folder on the file system.
Figure 1: Oracle ADF Security design time and runtime architecture
For testing applications by using Oracle WebLogic Server integrated with Oracle JDeveloper, security policies defined in jazn-data.xml are copied into the system-jazn-data.xml policy file in the config\fmwconfig directory of the target Oracle WebLogic Server domain. In this scenario, user identities and enterprise roles defined in the jazn-data.xml file are deployed to the integrated Oracle WebLogic Server in Oracle JDeveloper.
In a production environment, user identities and enterprise roles defined in the application jazn-data.xml file generally cannot be deployed to Oracle WebLogic Server instances. On a production server, user authentication is instead performed with the identity management system set up for the enterprise. Typical mechanisms include LDAP, RDBMS, Oracle Internet Directory, and Microsoft’s Active Directory.
Sample Application Overview
This article walks through a sample application designed to show how Oracle ADF Security and Oracle platform security services work. You can download this application, containing configuration and code examples for you to explore at design time and runtime, at oracle.com/technetwork/issue-archive/2011/12-jan/o12adf-524995.zip.
To get started, make sure you have an Oracle Database instance installed and running, with the HR schema unlocked. Then unzip the o12adf-524995.zip file into a directory on your local machine. Next, launch Oracle JDeveloper 11g Release 2, select File -> Open, and navigate to the directory where you unzipped the sample application. In the OramagAdfSecurity folder, select the OramagAdfSecurity.jws file and click Open.
The sample application contains three projects: EmployeeEdit, Model, and ViewController. The Model project contains a business service, based on Oracle ADF’s Business Components feature, that queries the Departments and Employees tables in the HR schema.
The EmployeeEdit project defines a single bounded task flow, edit-employees-flow-btfsdc, that edits a selected employee record. Because it is designed as a reusable task flow deployed in an Oracle ADF library, this project would usually be created in a separate Oracle JDeveloper workspace. For this simple demo, however, it is part of the OramagAdfSecurity.jws workspace.
The ViewController project references the edit-employees-flow-btfsdc task flow described above. To see this reference, double-click the ViewController project node and expand the Libraries and Classpath node in the dialog box that appears. Select ADF Library, and click Edit to see the ADF Library reference and understand how to authorize application content located in ADF Library files.
Before running the sample application, change the database configuration to point to an accessible HR database schema. In Oracle JDeveloper, select View -> Database -> Database Navigator. Expand the OramagAdfSecurity node, right-click the hrconn node, and choose Properties from the context menu to edit the database connection information. Close the configuration dialog box by clicking OK after applying the changes.
Run the sample application by opening the Oracle JDeveloper Application Navigator. Expand the ViewController project node, and select the Home.jsf page from the Web Content folder. Right-click Home.jsf, and select Run from the context menu. (If this is the first time you have run an application in Oracle JDeveloper and you see a Create Default Domain dialog box asking you to create the Oracle WebLogic Server domain, fill out the form fields and click OK.)
Figure 2 shows the running application. Click the application Login link, and try authenticating as sking (HR manager), ahunold (Manager), and dfaviet (Employee). The password for all three accounts is welcome1.
Figure 2: Oracle ADF Security sample application
The sample application enforces the following security rules for the different users:
After a user has been successfully authenticated, the Login link changes to a Logout link to allow logout and login as a different user.
Enabling Oracle ADF Security
By digging deeper inside the sample Oracle ADF application, you can see how the security rule definitions described above are implemented for the three defined user accounts.
The first step in securing an application is to enable Oracle ADF Security. In the OramagAdfSecurity project, select Application -> Secure -> Configure ADF Security to open the Oracle ADF Security wizard. This wizard is re-entrant, so you can safely open it and browse security settings without worrying about losing data.
The first dialog box in the configuration wizard enables you to define the type of security you want. The ADF Authentication and Authorization option, used in the sample application, enables you to configure login information as well as access to specific application features. Another option, ADF Authentication, is for controlling only who can access the application (via a login dialog box when a user requests access to the application). The Remove ADF Security Configuration option does not delete any existing policy definitions, but it disables the enforcement of Oracle ADF Security. This option can be useful for allowing application testing while temporarily disabling security.
The next dialog box, Select Authentication Type, is where you define the type of authentication to use (such as form-based or basic). The authentication mechanism you choose depends on whether you want to provide your own login form or if you want to use client browser certificates for authentication.
The sample application uses basic authentication, which performs programmatic authentication leveraging a specific Oracle WebLogic Server-proprietary API. If you select form-based authentication instead, Oracle JDeveloper will generate a login form for you. The login form, built in HTML, is configured in the web.xml file of your Web project.
The next dialog box, Enable Automatic Policy Grants, enables you to define how to protect existing resources, views, and task flows in your project.
For large projects, you would ideally choose the No Automatic Grants option, which basically locks the application down until you explicitly grant access permissions to application roles and then map those application roles to users and enterprise roles defined in the jazn-data.xml file.
Alternatively, the Grant to Existing Objects Only option enables authentication and authorization for an Oracle ADF application while ensuring that the application remains accessible to everyone. Use this option to enable security for an existing application without interrupting the current development process. With this option, pages and task flows created after security is enabled are not accessible, by default. To make them accessible, you need to explicitly grant them to application roles defined in the application.
The Grant to All Objects option is similar to Grant to Existing Objects Only, except that it also grants all users access to new pages and task flows created after security is enabled. Use this option to add security to an application for which you don’t have any application roles or user identities defined.
The next wizard dialog box, Specify Authentication Welcome Page, is where you define a landing pad—a page to which all authenticated users are redirected after login. If this option is not set, the redirect will go to the protected view that triggered the authentication process.
When you are done, click Finish to close the Specify Authentication Welcome Page dialog box and the Oracle ADF Security wizard.
Creating Users, Enterprise Roles, and Application Roles
Before building authorization into Oracle ADF applications, you need to create users, enterprise roles, and application roles for testing. Oracle JDeveloper provides a declarative configuration console where you can easily create users and enterprise roles that simulate identities as they would exist in the identity management system in a production environment.
Application roles in Oracle ADF Security are specific to an application and decouple security grants from identities. Upon deployment, application roles are copied to the policy store. Although you can grant permissions to users and enterprise roles directly, it is not recommended—you should use application roles instead.
To create users and enterprise roles, select Application -> Secure -> Users. If you do this for the sample application, you will see user accounts for Steven King, Alexander Hunold, and David Faviet.
Next, select the Enterprise Roles tab, as shown in Figure 3.
Figure 3: To create enterprise roles, click the Enterprise Roles tab.
The sample application has three enterprise roles defined: Enterprise Employee Group, Enterprise HR Manager Group, and Enterprise Manager Group. Individual user identities can be assigned to one or many roles.
Select the Application Roles tab to create application roles to which you will later grant resource permissions. Application roles are mapped to users and enterprise roles available on the target server. (The sample application has three application roles defined.)
Enabling Security in Oracle ADF Business Components
When you enable Oracle ADF Security for an application, the change does not immediately affect Oracle ADF Business Components. To enforce authorization on an Oracle ADF Business Component entity or entity attribute, locate the entity in the Oracle JDeveloper Application Navigator and right-click it. In the sample application, entity security is defined on the Employees entity, which can be found in the Model project in Application Sources -> adf.sample.model -> model -> entities.
To view entity security options in the sample application, right-click the Employees entity and select Open Employees to open the entity editor. In the editor, expand the Security node of the General category and select the entity actions on which you want to enforce framework security. Oracle ADF Business Component entities can be protected for read, update, and removal.
To secure entity attributes, select an attribute in the Attributes section of the entity editor and select the Security tab. Attributes can be protected against update. When this option is enabled, only authorized users can see editable input fields in the user interface for the selected attribute.
In the sample application, the Employees entity’s security configuration is set up so that only HR managers can change the salary of an existing employee. You can test this configuration by running the application and testing the User Profile tab after being authenticated as both ahunold and sking.
Note that although the steps described above enable entity security in Oracle ADF Business Components, they don’t define which specific roles are authorized for access. The next step shows how these security policies are defined.
Defining Security Policies
A security policy is a rule that defines the users who can access a resource, along with the actions they can perform on it. Technically, policies associate access permissions with application roles by using a GRANT statement.
At runtime, security policies are enforced on a resource by Oracle ADF or programmatically in the application with either specialized EL or Java.
Enabling Oracle ADF Security for an application immediately secures application pages in all unbounded and bounded task flows. The protection of other resources such as Oracle ADF Business Component entities, entity attributes, and custom resources such as menu items and Java methods in Oracle ADF is optional but recommended.
Pages and page fragments contained in bounded task flows are not separately checked for security but, rather, run under the protection defined for the bounded task flow. If a page or a page fragment in a bounded task flow requires extra security to be enforced by the framework, you can enable this declaratively by moving the page or the page fragment into its own task flow or by issuing a manual permission check, using Oracle ADF security expressions or Java.
An example of a manual permission check is a router activity in a task flow that navigates to different views, depending on user-granted permissions. The next section (“Using Security Expressions”) shows how to use security expressions to manually protect views and controller activities.
Oracle ADF Security provides a visual and declarative environment to enable developers to define security policies in the jazn-data.xml file. To open the Oracle ADF Security policy editor (as shown in Figure 4), select Application -> Secure -> Resource Grants.
Figure 4: To edit resource grants, click the Resource Grants tab.
The Resource Type and Source Project fields are where you select the type of resource and a project filter, and Oracle JDeveloper lists all available resources used in the application that meet these criteria. For example, Figure 4 shows all the task flow resources available in the ViewController project. If you also want to see task flows contained in Oracle ADF libraries (such as edit-employees-flow-btfsdc in the provided sample application), check the Show task flows imported from ADF checkbox. For a selected task flow resource, use the green plus (+) icon to grant access to users, enterprise roles, application roles, or code sources. Note that for task flows and page views, you can grant only the “view” action. Grants of other actions listed for task flows are enforced only with Oracle WebLogic.
Among the other framework-provided resource types are ADF Entity Object, ADF Entity Object Attribute, Web Page, and custom resource permissions. You can use custom resource permissions to perform manual security checks for user access to menus, tabs, or custom application functionality. To create new resource permissions, click the green plus (+) icon next to the Resource Type field.
A custom resource permission is defined by a name, a permission class, and a list of actions that can be performed on it. For example, the sample application uses a custom permission named InsertEntityAttribute to define the user privilege to update an attribute while a row is new. The custom permission uses the oracle.security.jps.ResourcePermission class at runtime and has a single action—“insert”—defined. The InsertEntityAttribute resource permission is checked programmatically with Java in the isAttributeUpdateable method contained in the adf.sample.model.entities.EmployeesImpl class of the Model project. With the InsertEntityAttribute permission in the sample application, managers such as ahunold can update a salary only when an employee record is newly created.
Another custom resource permission in the sample application is PanelTabProtection, which Oracle ADF Security EL checks in the rendered attribute of the af:showDetail item component that represents the HR Managers Only tab.
In the Security Policy editor, the Entitlement Grants tab enables you to group resources that have the same access protection requirements to be granted in a single grant statement. The concept of entitlements in Oracle ADF Security simplifies security administration, because you don’t need to grant access to individual resources. Instead, you can perform grants by using a single bulk statement.
The sample application has a single Public Task Flows entitlement defined, which references all task flows accessible to all employees.
To create new entitlements in your custom project, click the green plus (+) icon next to the Entitlements header and define a name for the new security group. Then click the green plus (+) icon on the Resources tab to choose the resources to combine in this entitlement. When selecting a resource type in the Select Resources dialog box, ensure that the Resource Projects field contains the name of the project that holds the resource. If a project is not shown, use the magnifier icon to add it to the list of projects.
Using Security Expressions
For checking security in the user interface or in the Oracle ADF binding layer, Oracle ADF provides the following set of specialized security expressions:
To add a security expression to a user interface component, select the component in the visual page editor and open the Property Inspector. Click the down-arrow icon to the right of the property to which you want to add the expression (such as the disabled property on an af:showDetail item on a panel tab). Choose Expression Builder from the context menu that appears.
In the Expression Builder, expand the ADF Bindings node and the securityContext node it contains. To get help on how to use an expression, expand the Description node at the bottom of the expression editor.
The sample application uses security expressions on the Home.jsf page to enable and disable panel tabs, based on the user authentication state and that person’s role membership. The browse-employees-btf.xml task flow definition in the WEB-INF\regions folder uses security expression on the edit-employees-flow-btfsdc task flow call activity to skip the train stop for all users except HR managers.
Using Java for Security
All permissions in Oracle ADF Security are represented at runtime by a Java class that can be instantiated and dynamically checked. Commonly used classes are
The sample application checks Oracle ADF Security from Java in two places: in the EmployeesImpl.java file in the Model project and in the UserSearchBean.java managed bean in the ViewController project. The entity implementation class has a security check for a custom resource permission that allows managers (such as ahunold) to update employee salaries for newly created employee records. The permission check in the managed bean verifies the user privilege to access the task flow referenced by a dynamic region and returns an empty region if permission is not granted. This check is also an example of defense in depth, in that task flow security is also checked by the framework.
Oracle ADF Security simplifies a complex topic by abstracting JAAS authorization and Java EE authentication. With Oracle ADF, you use visual editors to protect the resources you care about the most and enforce security configurations. You can also use security expression language or Java in applications to verify user access rights. With all the simplicity added, the most important thing to be aware of is that applying security to an application is a journey and not a destination.
Frank Nimphius is a senior principal product manager for Oracle JDeveloper and Oracle Application Development Framework. He is a coauthor of Oracle Fusion Developer Guide: Building Rich Internet Applications with Oracle ADF Business Components and Oracle ADF Faces (McGraw-Hill, 2010).