Skip Headers
Oracle® Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework
11g Release 1 (11.1.1)

Part Number B31974-02
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Feedback page
Contact Us

Go to previous page
Previous
Go to next page
Next
View PDF

28 Adding Security to a Fusion Web Application

This chapter describes how to use Oracle ADF Security in your Fusion web application to handle authentication and authorization when you test your application in JDeveloper and later when you deploy the application to Oracle Application Server.

This chapter includes the following sections:

28.1 Introduction to ADF Security for Fusion Web Applications

Oracle ADF implements a Java Authentication and Authorization Service (JAAS) security model through integration with the Oracle Platform Security for Java implementation of the JAAS service. The JAAS model implements authentication in a pluggable fashion, so applications can remain independent from the underlying authentication technology. However, JAAS still requires custom code at the application level that makes implementing authorization more difficult. Oracle ADF Security simplifies the implementation of a JAAS authorization model by exposing it in a declarative fashion on various Fusion web application resources that JDeveloper supports.

This declarative support for securing Fusion web application resources is not based on the URL mapping of a security constraint. Oracle ADF Security lets you define an access policy for a variety of application resources. For example, you can control access to a particular task flow based on the access right grants that you make in the policy store for the ADF task flow. During development, this policy store is file-based, with access right grants stored in the jazn-data.xml file, whereas the identity store can be file-based or LDAP-based, with grants stored in an LDAPv3-compliant directory, such as Oracle Internet Directory.

At runtime, the grants you define for Fusion web application resources will be enforced using standard JAAS permission authorization to determine the user's access rights. If your application requires it, you can use Expression Language (EL) to surface server-side security enforcement directly on the user interface. You might use an EL expression to perform runtime permission checks within the web page to hide components that should not be visible to the user with insufficient privileges. You can also use Oracle ADF Security's implementation of expressions that are specific to the ADF task flow and ADF page definition to perform permission checks to prevent the user from being able to access a task flow or web page.

Within the Oracle ADF framework, JAAS-based security is enforced by the ADF binding servlet filter and the ADF Model layer of the application. The filter is configured to protect ADF resources and requires the current user to have sufficient access right grants to view the ADF resource.

The use of Oracle ADF Security enables web applications to easily adjust to real-world business security requirements, because rather than securing paths, you secure the actions of ADF resources with JAAS. JAAS-based Oracle ADF Security provides:

Note:

When you want to understand the security features of Oracle WebLogic Server, see Oracle WebLogic Server Understanding WebLogic Server.

28.2 Choosing ADF Security Authentication and Authorization

JDeveloper and Oracle ADF Security allow you to choose to enable authentication and authorization separately. You may choose to:

Oracle ADF Security supports these two choices to leave you the option to rely on container-managed security constraints and still be able to support dynamic login using the ADF authentication servlet. In this case, the servlet will require the user to log in the first time a page in the application is accessed. The servlet will also redirect the user to the requested page when the user has sufficient access rights as defined by security constraints. In this case, the developer is responsible for defining security constraints for web pages.

When you prefer to define fine-grained security using ADF authorization, that option is also available. In this case, when choosing to enforce ADF authorization, you are responsible for specifying access right grants needed to make the ADF resources accessible to users. This step requires configuring a policy store that consists of grants made to specific application roles. You should plan on performing the following tasks:

  1. Define application roles and assign members to those roles.

    As a convenience, the Configure ADF Security wizard lets you define the test-all role to enable the members of this role to access all ADF resources. For details about the test-all role, see Section 28.3.1, "How to Enable the test-all Application Role in JDeveloper".

  2. Make Permission grants to the roles in the policy editor for ADF resources.

    When you enable the test-all role, the Configure ADF Security wizard will also make automatic "View" grants to the test-all role for the ADF resources that your application contains. You can then associate members with the test-all role, as described in Section 28.3.3, "How to Configure the Identity Store with Test Users in JDeveloper". As the application roles become known, you can eventually replace all these automatic grants with ones that define the production application's roles (rather than the test-all role).

To manage these choices for authentication and authorization, you use the Configure ADF Security wizard in JDeveloper.

To launch the Configure ADF Security wizard:

  1. In the Application Navigator, select the user interface project that contains the web pages and web.xml file.

    Caution: The Configure ADF Security wizard updates the web.xml file in the context of the project that appears selected in the Application Navigator. Before you run the wizard, make sure to select the user interface project in the Application Navigator. You can accomplish this by selecting any file or folder in the user interface project that you want to secure.

  2. In the JDeveloper toolbar, choose Configure ADF Security from the Tools menu, as shown in Figure 28-1.

Figure 28-1 Launching the Configure ADF Security Wizard from the Tools Menu

ADF Security wizard in Tools menu

The first page of the wizard lets you choose one of three options, with the default option set to enable ADF Authentication and Authorization, as shown in Figure 28-2.

Figure 28-2 The Default Option in the Configure ADF Security Wizard

First page of the ADF Security wizard

When you run the wizard with the default option selected, it will enable the ADF authentication servlet to handle user authentication dynamically. The wizard will add two constraints, allPages and adfAuthentication, to the web.xml file. The allPages constraint is mapped to the '/' URL. This mapping means that the first time the user accesses any page, login will be triggered. For a complete description of how ADF Security handles authentication, see Section 28.2.8, "What Happens at Runtime: How Oracle ADF Security Handles Authentication".

Note:

If you remove this allPages constraint from the web.xml file, you could provide a login link or button to explicitly trigger login. You could also have a link or button to perform logout.

The default option of the wizard will also enforce authorization. When you enforce authorization, all task flows and the web pages they contain and, additionally, any web page not contained by a task flow that is defined by an associated ADF page definition will be secure by default. This means that these web pages associated with ADF resources will require a security policy to grant access or they will remain inaccessible to the authenticated user. When you enforce authorization of ADF resources it means that you intend to secure access to ADF application resources and then allow certain application roles access to these resources by defining appropriate grants in the policy store. For a description of how ADF Security enforces authorization, see Section 28.2.9, "What Happens at Runtime: How Oracle ADF Security Handles Authorization".

As a convenience, the wizard prompts you to provide automatic grants to the test-all role. By using the wizard to grant to the test-all role, you can postpone defining explicit grants to ADF resources until you are ready to refine the access policy of your application. Then, as application development progresses and the content of the application becomes well-established, you can replace grants to the test-all role with the production application roles and explicit permission grants. The explicit grant establishes the necessary privilege (for example, View on a page) to allow users to access these resources. For details about ADF security policies, see Section 28.4, "Defining ADF Security Access Policies".

If you prefer instead not to enforce authorization of ADF resources, you can choose the ADF Authentication option. When you run the wizard with this option selected, it will enable the ADF authentication servlet to handle user authentication dynamically. Since the wizard does not enforce authorization for this option, no permission checking is performed for ADF resources. Therefore, once the user logs in, all ADF resources will be considered public and consequently all web pages will be accessible to the authenticated user.

The remaining option, Remove ADF Security Configuration, lets you disable the ADF authentication servlet for as long as you require. This option will appear enabled only if you have configured ADF Security with the wizard. You may select this option with the intention of reenabling ADF Security at any time. When you run the wizard with this option selected, the wizard removes ADF-specific metadata in the web.xml file and adf-config.xml file. The wizard specifically does not alter the policy store of the application, which contains the Permission metadata that application developers defined for ADF resources. For example, if the application uses the standard XML provider as the policy store, the jazn-data.xml file will remain unchanged by this option. This means that you can return to the wizard at any time, select the ADF Authentication and Authorization option, and reenable security against your application's existing policy and identity stores.

In summary, the Configure ADF Security wizard provides these three options, which you can select as required:

Note:

For more information about the choices you have for working with Java EE security, see "Roadmap for Developing Secure Applications" in the "Developing Secure Applications" section of the JDeveloper online help.

28.2.1 How to Enable Only ADF Authentication

After you run the Configure ADF Security wizard with the ADF Authentication option selected in the ADF Security page, you will have configured a security constraint against the ADF authentication servlet and enabled dynamic authentication. The wizard updates all security-related configuration files and ensures that the ADF authentication servlet enforces user authentication. With this option selected, Oracle ADF Security will not check Permission metadata that may have been created for ADF task flows and ADF bindings; and all ADF resources will be available to the user.

To enable authentication without resource authorization:

  1. In the Application Navigator, select the user interface project that contains the pages that you want to secure. Do not select the data model project or any other project.

  2. From the Tools menu, choose Configure ADF Security, as shown in Figure 28-1.

  3. In the ADF Security page, select ADF Authentication, as shown in Figure 28-3. Click Next.

    This selection configures the ADF authentication servlet. This will allow the servlet to set the security context to create an authenticated Subject (a container object that represents the user), as described in Section 28.2.8, "What Happens at Runtime: How Oracle ADF Security Handles Authentication".

    Figure 28-3 Enabling Only Authentication in the Configure ADF Security Wizard

    Authentication in the wizard
  4. In the Authentication Type page, select the authentication type that you want your application to use when the user submits their login information. Click Next.

    The most commonly used types of authentication are HTTP Basic Authentication and Form-Based Authentication. Basic authentication uses the browser login dialog for the user to enter a username and password. Note that with Basic authentication, the browser caches credentials from the user, thus preventing logout. Basic authentication is useful when you want to test the application without requiring a custom login page. Form authentication allows the application developer to specify a custom login UI.

    If you select Form-based Authentication, you can also select Generate Default Pages to allow the wizard to generate a default login and error page. Alternatively, you can create your own pages.

    For more information about handling user login, see Section 28.5, "Handling User Authentication in a Fusion Web Application".

  5. In the Identity Store page, select the type of repository to store the user and role information for authentication purposes. Click Next.

    The repository associated with the security provider can be an XML file or a directory service. Both repository types are supported by JDeveloper's Integrated WLS. However, when you choose the LDAP identity store, you must configure the LDAP store outside of JDeveloper. When you choose the application XML identity store, you can configure user and role information within JDeveloper using the editor for the jazn-data.xml file. This step will allow you to add users to the identity store so that you can run the application in JDeveloper and authenticate test users.

    For more information about adding users to the identity store, see Section 28.3, "Defining Users and Roles for a Fusion Web Application".

  6. In the Authenticated Welcome page, optionally specify a web page that the application will use to redirect the authenticated Subject to. Click Next.

    Use to direct the user to a specific page after they log in. The application will use the specified web page only when a destination page is not specified as a parameter to the ADF authentication servlet. Typically, the application will specify a destination page as part of the success_url parameter. In particular, one is specified by Oracle ADF when the application attempts to access a web page that requires ADF authorization and the user is not yet logged in, as described in Section 28.2.8, "What Happens at Runtime: How Oracle ADF Security Handles Authentication". If you do not specify a redirect web page, the servlet will direct the user back to the page from which login was initiated.

  7. In the Summary page, review your selections and click Finish.

28.2.2 What Happens When You Choose Not to Enforce Authorization

Table 28-1 shows which files the Configure ADF Security wizard updates when you complete the wizard with the ADF Authentication option selected.

Table 28-1 Files Updated for ADF Authentication

File File Location Configuration Performed by the Configure ADF Security Wizard

web.xml

/public_html/WEB-INF folder relative to the user interface project

  • Oracle JpsFilter filter definition required for ADF authorization.

  • Oracle adfAuthentication servlet definition.

  • Servlet mapping for the ADF authentication servlet.

  • Security constraint on the ADF authentication servlet.

  • Login configuration.

  • Required security roles, including the role valid-users, which is used to trigger authentication.

adf-config.xml

/.adf/META-INF folder relative to the web application workspace

  • JAAS security context.

  • The use of the ADF authentication servlet is enforced (authenticationRequire property in the <JaasSecurityContext> element is set to true). This property is used in J2SE applications to trigger displaying a login dialog.

  • The use of security policies for ADF resources are ignored and no permission checking is performed (the authorizationEnforce parameter in the <JaasSecurityContext> element is set to false).

jps-config.xml

%domain.home%/config folder relative to the domain.home environment variable

  • Oracle Platform Security context for the credential store.

  • Oracle Platform Security context for the policy store.

  • Oracle Platform Security context for anonymous user, which contains the anonymous service instance and the anonymous login module.

weblogic.xml

/src/META-INF folder relative to the web application workspace

  • Role mapping of the valid-users security role to the Oracle Platform Security principal, users.

jazn-data.xml

./src/META-INF folder relative to the web application workspace

  • Default jazn.com realm name for the XML file-based identity store.


As authentication is delegated to the web container, the wizard updates the web.xml file to define an adfAuthentication resource that uses a URL pattern against the ADF authentication servlet, as shown in Figure 28-4. This constraint allows for the definition of a single standard URL that can be used as a login or logout link throughout the application. Java EE container-managed security defines a standard method for login. There is no standard to log out of an application, so while the login process is delegated to the container, the logout process is handled by the ADF authentication servlet itself.

Figure 28-4 Security Constraint Defined by Configure ADF Security Wizard

adfAuthentication resource definition in web.xml

Note:

You must not delete the adfAuthentication constraint from the web.xml file. Deleting it would prevent users from logging in to the application in the manner supported by Oracle ADF. Any other static security constraints would continue to work and invoke a login if required.

Because every user of the application is required to be able to log in, the security constraint defined against the ADF authentication servlet should allow all users to access this web resource. As such, the security role associated with the constraint should encompass all users. To simplify this task, the Java EE valid-users role is provided, as shown in Figure 28-5. The the web.xml file maps this role to a special authenticated-role principal defined by Oracle Platform Security. This mapping ensures that every user will have this role because every properly authenticated user will have the authenticated-role principal added to their Subject by Oracle Platform Security, as described Section 28.2.3, "What You May Need to Know About the valid-users Role". From a security perspective, the valid-users role lets you control access to web resources using only security constraints. The end result of this mapping relies entirely on Java EE security and does not involve JAAS Permissions.

Figure 28-5 valid-users Role Defined by Configure ADF Security Wizard

valid-users security role in web.xml

You may also use this page to add further security constraints on web resources used by the application, as described in "Securing Web Pages Using a Security Constraint" in the "Developing Secure Applications" section of the JDeveloper online help.

28.2.3 What You May Need to Know About the valid-users Role

The valid-users role is a Java EE security role defined by ADF Security to trigger the authentication of the user by the security constraint on the adfAuthentication web resource defined in the web.xml file. The Configure ADF Security wizard updates the weblogic-application.xml file to map this ADF security role to the authenticated-role principal. The authenticated-role is a special principal defined by Oracle Platform Security and serves a purpose similar to an enterprise role. At runtime, the principal is added automatically to a successfully authenticated Subject by Oracle Platform Security.

28.2.4 How to Enable ADF Authentication and Authorization

After you run the Configure ADF Security wizard with the ADF Authentication and Authorization option selected in the ADF Security page, you will have configured a security constraint against the ADF authentication servlet, enabled dynamic authentication, and enabled ADF permission checking. The wizard updates all security-related configuration files and ensures that ADF resources are secure by default.

When you run the Configure ADF Security wizard to enable authorization of ADF resources, you are not required to have a policy store in place. Permission checking can still take place using the test-all role that you can enable in the wizard. If you define this role, and associate those members with the role, members from the identity store will be granted automatic view access on ADF resources, as described in Section 28.3, "Defining Users and Roles for a Fusion Web Application". This allows you to run and test your application before creating the policy store.

Eventually, you will want to make grants to customize the ADF resource access rights for members of actual application roles. For complete information about how to customize the policy store so that your application has fine-grained control over access privileges on ADF resources, see Section 28.4, "Defining ADF Security Access Policies".

To enable authentication and authorization of ADF resources:

  1. In the Application Navigator, select the user interface project that contains the pages you want to secure. Do not select the data model project or any other project.

  2. From the Tools menu, choose Configure ADF Security.

  3. In the ADF Security page, select ADF Authentication and Authorization, as shown in Figure 28-6.

    This selection configures the ADF authentication servlet. This configuration will allow the servlet to set the security context and check for ADF authorization privileges.

    Figure 28-6 Enabling Authorization in the Configure ADF Security Wizard

    Authentication and authorization in the wizard
  4. In the Authentication Type page, select the authentication type that you want your application to use when the user submits their login information. Click Next.

    The most commonly used types of authentication are HTTP Basic Authentication and Form-Based Authentication. Basic authentication uses the browser login dialog for the user to enter a username and password. Note that with Basic authentication, the browser caches credentials from the user, thus preventing logout. Basic authentication is useful when you want to test the application without requiring a custom login page. Form authentication allows the application developer to specify a custom login UI.

    If you select Form-based Authentication, you can also select Generate Default Pages to allow the wizard to generate a default login and error page. Alternatively, you can create your own pages.

    For more information about these user login options, see Section 28.5, "Handling User Authentication in a Fusion Web Application".

  5. In the Identity Store page, select the type of repository to store the user and role information for authentication purposes. Click Next.

    The repository associated with the security provider can be an XML file or a directory service. Both repository types are supported by JDeveloper's Integrated WLS. However, when you choose the LDAP identity store, you must configure the LDAP store outside of JDeveloper. When you choose the application XML identity store, you can configure user and role information within JDeveloper using the editor for the jazn-data.xml file. This step will allow you to add users to the identity store so that you can run the application in JDeveloper and authenticate test users.

    For more information about adding users to the identity store, see Section 28.3, "Defining Users and Roles for a Fusion Web Application".

  6. In the Automatic Policy Grants page, select whether to make ADF resources public without requiring application developers to first define ADF policy grants. Click Next.

    When you enable automatic policy grants, a "View" grant will be made to all members of the test-all application role. This option provides a convenient way to run and test application resources without the restricted access that ADF authorization enforces. To enable this option, you can select either Grant to Existing Objects Only or you can select Grant to All Objects. The choice between existing objects and all objects lets you test your application resources either as developers add them (all objects) or you can limit testing so that new resources remain inaccessible (only existing objects). After you enable the automatic policy grant in the wizard, you must add a test user to the test-all role. Alternatively, if you want to run the application without restriction, you can assign anonymous-role as a member of the test-all role. For details about adding members to the test-all role, see Section 28.3.3, "How to Configure the Identity Store with Test Users in JDeveloper".

    Otherwise, when you are ready to configure ADF policy grants to secure ADF resources, select No Automatic Grants.

    Note:

    If you select No Automatic Grants, all ADF resources will be secure by default. Thus the step of configuring a policy store is necessary to make the web pages and task flows accessible to authenticated users. For details about the granting access to ADF resources, see Section 28.4, "Defining ADF Security Access Policies".
  7. In the Authenticated Welcome page, optionally, select Redirect Upon Successful Authentication when you want to direct the user to a specific web page after they log in. Click Next.

    If not selected, the ADF authentication servlet directs the user back to the page from which the login was initiated.

    Note that if the web page you specify contains ADF Faces components, you must define the page in the context of /faces/. For example, the path for adffaces_welcome.jspx would appear in the Welcome Page field as /faces/adffaces_welcome.jspx.

  8. In the Summary page, review your selections and click Finish.

28.2.5 What Happens When You Choose to Enforce Authorization

Table 28-2 shows which files the Configure ADF Security wizard updates.

Table 28-2 Files Updated for ADF Authentication and Authorization

File File Location Configuration Performed by the Configure ADF Security Wizard

web.xml

/public_html/WEB-INF folder relative to the user interface project

  • Oracle JpsFilter filter definition required for ADF authorization.

  • Oracle adfAuthentication servlet definition.

  • Servlet mapping for the ADF authentication servlet.

  • Security constraint on the ADF authentication servlet.

  • Login configuration.

  • Required security roles, including the role, valid-users, which is used to trigger authentication.

adf-config.xml

/.adf/META-INF folder relative to the web application workspace

  • JAAS security context.

  • The use of the ADF authentication servlet is enforced (authenticationRequire parameter in the <JaasSecurityContext> element is set to true). This property is used in J2SE applications to trigger displaying a login dialog.

  • The use of ADF Security metadata is enforced for permission checking (the authorizationEnforce parameter in the <JaasSecurityContext> element is set to true).

jps-config.xml

%domain.home%/config folder relative to the domain.home environment variable

  • Oracle Platform Security context for the credential store.

  • Oracle Platform Security context for the policy store.

  • Oracle Platform Security context for anonymous user, which contains the anonymous service instance and the anonymous login module.

weblogic.xml

/src/META-INF folder relative to the web application workspace

  • Role mapping of the valid-users security role to the Oracle Platform Security principal, users.

jazn-data.xml

./src/META-INF folder relative to the web application workspace

  • Default jazn.com realm name for the XML file-based identity store.


Specifically, when you select ADF Authentication and Authorization in the wizard, it sets the authorizationEnforce parameter in the <JaasSecurityContext> element to true. This allows the ADF security context to get the user principals from the HttpServletRequest once the user is authenticated by the container. For example, if a user clicks a link to a protected page and this user is not authenticated, the ADF authentication servlet is called and the web container invokes the login page. The user submits a user name and password and that data is compared against the data in the identity store where user information is stored. If a match is found, the originator of the request (the user) is authenticated. The user name is then stored in the ADF security context, where it can be accessed to obtain other security-related information (such as the group the user belongs to) in order to determine authorization rights.

You can proceed to define application roles and ADF security policies. The ADF security policy consists of a permission grant applied to the ADF resource and assigned to the desired application role. Until you complete this step, all ADF resources are considered private and inaccessible even to authenticated users. Application roles are stored in the policy store and have no relationship to the identity store used to specify users and enterprise roles.

Note that you use different editors to define application roles and ADF security policies. You open both editors from the jazn-data.xml file, which appears in the Descriptors/META-INF node of the Application Resources panel:

  • To define the security policies, you open the overview editor for the jazn-data.xml file by double-clicking the file.

  • To define application roles, you open the Edit JPS Identity and Policy Store editor for the jazn-data.xml file by right-clicking the file and choosing Edit.

28.2.6 How to Disable ADF Security

If you want to run the application without using Oracle ADF Security, open the Configure ADF Security wizard, select Remove ADF Security Configuration on the first page and all security will be turned off.

To disable ADF Security for the application:

  1. In the Application Navigator, select the user interface project that contains the pages you want to secure. Do not select the model project or any other project.

  2. From the Tools menu, choose Configure ADF Security.

  3. In the ADF Security page, select Remove ADF Security Configuration, as shown in Figure 28-7.

    This selection will undo all ADF security-related configuration definitions from the web.xml file and the adf-config.xml file.

    Figure 28-7 Disabling ADF Security in the Configure ADF Security Wizard

    Remove ADF Security option in wizard
  4. Click Next and then click Finish. All other wizard pages

28.2.7 What Happens When You Disable ADF Security

Table 28-3 shows which files the Configure ADF Security wizard updates.

Table 28-3 Files Updated When Disabling ADF Security

File File Location Configuration Performed by the Configure ADF Security Wizard

web.xml

/public_html/WEB-INF folder relative to the user interface project

  • Removes the Oracle adfAuthentication servlet definition.

  • Removes servlet mapping for the ADF authentication servlet.

  • Removes the constraint on the ADF authentication servlet.

  • Removes the login configuration.

  • Removes security role valid-users.

adf-config.xml

/.adf/META-INF folder relative to the web application workspace

  • Removes the JAAS security context.

  • Removes the authenticationRequired and authorizationEnforce parameters in the <JaasSecurityContext> element.

weblogic.xml

/src/META-INF folder relative to the web application workspace

  • Security role mapping of valid-users principal.


28.2.8 What Happens at Runtime: How Oracle ADF Security Handles Authentication

Figure 28-8 illustrates the authentication process when the user attempts to access any page containing ADF resources (such as mypage.jspx) without first logging in. Authentication is initiated implicitly because the user does not begin log in by clicking a login link on a public page. In the case of the secured page, no grants have been made to the anonymous user.

Figure 28-8 Oracle ADF Security Implicit Authentication

ADF security implicit authentication process

In Figure 28-8, the implicit authentication process assumes the resource does not have a grant to the anonymous-role role, that the user is not already authenticated, and that the authentication method is form-based authentication. In this case, the process is as follows:

  1. When the web page (or ADF task flow) is requested, the ADF bindings servlet filter redirects the request to the Oracle ADF authentication servlet (Step 1), storing the logical operation that triggered the login.

  2. The ADF authentication servlet has a Java EE security constraint set on it, which results in the Java EE container invoking the configured login mechanism (Step 2). Based on the container's login configuration, the user is prompted to authenticate:

    1. The appropriate login form is displayed for form-based authentication (Step 2a).

    2. The user enters his credentials in the displayed login form (Step 2b).

    3. The user posts the form back to the container's j_security_check() method (Step 2c).

    4. The Java EE container authenticates the user, using the configured pluggable authentication module (Step 2d).

  3. Upon successful authentication, the container redirects the user back to the servlet that initiated the authentication challenge, in this case, the ADF authentication servlet (Step 3).

  4. On returning to the ADF authentication servlet, the servlet subsequently redirects to the originally requested resource (Step 4).

    Whether or not the resource is displayed will depend on the user's access rights and whether authorization for ADF Security is enforced, as explained in Section 28.2.9, "What Happens at Runtime: How Oracle ADF Security Handles Authorization".

Figure 28-9 illustrates the explicit authentication process when the user becomes authenticated starting with the login link on a public page.

Figure 28-9 Oracle ADF Security Explicit Authentication

ADF security explicit authentication process

In an explicit authentication scenario, an unauthenticated user (with only the anonymous user principal and anonymous-role principal) clicks the Login link on a public page (Step 1). The login link is a direct request to the ADF authentication servlet, which is secured through a Java EE security constraint in the web.xml file.

In this scenario, the current page is passed as a parameter to the ADF authentication servlet. As with the implicit case, the security constraint redirects the user to the login page (Step 2). After the container authenticates the user, as described in Step a through Step d in the implicit authentication case, the request is returned to the ADF authentication servlet (Step 3), which subsequently returns the user to the public page, but now with new user and role principals in place.

28.2.9 What Happens at Runtime: How Oracle ADF Security Handles Authorization

When ADF authorization is enabled, web pages that comprise an ADF task flow or any web page outside of a task flow that has an ADF page definition will be secure by default. When a user attempts to access these web pages, ADF Security checks to determine whether the user has been granted access in the policy store. If the user is not yet authenticated, and the page is not granted to the anonymous-role, then the application displays the login page or form. If the user has been authenticated, but does not have permission, a security error is displayed. If you do not configure the policy store with appropriate grants, the pages will remain protected and therefore stay unavailable to the authenticated user.

Figure 28-10 illustrates the authorization process.

Figure 28-10 Oracle ADF Security Authorization

ADF security authorization process

The user is a member of the application role Staff defined in the policy store. Because the user has not yet logged in, the security context does not have a Subject (a container object that represents the user). Instead, Oracle Platform Security provides Oracle ADF Security with a Subject with the anonymous user principal (a unique definition of the user) and the anonymous-role principal.

With the anonymous-role principal, typically the user would be able to access only pages not defined by ADF resources, such as the public.jsp page, whereas all pages that are defined either by an ADF task flow or outside of a task flow using an ADF page definition file are secure by default and unavailable to the user. An exception to security policy would be if you were to grant the anonymous-role role access to ADF resources in the policy store. In this case, the user would not be allowed immediate access to the page defined by an ADF resource.

When the user tries to access a web page defined by an ADF resource, such as mypage.jspx (which is specified by an ADF page definition, for example), the Oracle ADF Security enforcement logic intercepts the request and because all ADF resources are secured by default, the user is automatically challenged to authenticate (assuming that the anonymous-role is not granted access to the ADF resource, as previously mentioned).

After successful authentication, the user will have a specific Subject. The security enforcement logic now checks the policy store to determine which role is allowed to view mypage.jspx and whether the user is a member of that role. In this example for mypage.jspx, the View privilege has been granted to the Staff role and because the user is a member of this role, they are allowed to navigate to mypage.jspx.

Similarly, when the user tries to access secpage.jsp, another page defined by ADF resources, for which the user does not have the necessary View privilege, access is denied.

Users and roles are those already defined in the identity store of the resource provider. Application roles are defined in the policy store of the jazn-data.xml file.

28.3 Defining Users and Roles for a Fusion Web Application

Because web application security is based on a role-based access control mechanism with permissions granted to application roles, you must define a set of roles in the policy store that are specific to your application. For example, in the context of workflow, there may be roles such as customer, product specialist, supervisor, and administrator.

You will eventually map the application roles of your policy store to enterprise roles defined in the deployment environment. Mapping application roles will allow a user who is a member of a given enterprise role to access resources that are accessible from the associated application role. Enterprise roles are defined in the identity store of the security provider, such as system-jazn-data.xml, and are controlled only at an administrator level.

In the development environment, application roles exist in the jazn-data.xml file and are defined in <app-role> elements under <policy-store>. The location of the application policy store is application-root\src\META-INF\jazn-data.xml. Application roles are defined to represent the policy requirements of the application, regardless of what may eventually be mapped to them from the identity store. The use of application roles allows development to proceed against functional roles, as described in Section 28.3.2, "How to Define Application Roles in JDeveloper".

Note:

Application roles differ from roles that appear in the identity store portion of the system-jazn-data.xml file (defined in <role> elements under <jazn-realm>) or in roles defined by the enterprise LDAP provider. Application roles are specific to an application and defined in the application policy store. They are used by the application directly and are not necessarily known to Oracle WebLogic Server.

Because you will want to run your application in JDeveloper using Integrated WLS to test security, the Configure ADF Security wizard lets you generate the test-all application role, as described in Section 28.3.1, "How to Enable the test-all Application Role in JDeveloper". You can seed the identity store with users and then associate these test users with members of the test-all application role. Seeding the identity store with test users allows you to grant access rights to a few application roles and simulate the access rights of the application's actual users in a production environment. You edit the policy store in the jazn-data.xml file to associate the roles and their members, as described in Section 28.3.3, "How to Configure the Identity Store with Test Users in JDeveloper".

28.3.1 How to Enable the test-all Application Role in JDeveloper

When you run the Configure ADF Security wizard, you can add the test-all application role to the policy store in the jazn-data.xml file. When you enable this option in the wizard, you specify how you want grants to be made to the application role for ADF resources. The wizard lets you configure Oracle ADF Security so that JDeveloper will automatically add a View privilege to the policy store each time you or another application developer working on the user interface project creates a new ADF resource. Alternatively, you can choose to limit the grant to the just the existing ADF resources of the user interface project.

After you run the wizard and enable the test-all role, you can later rerun the wizard and disable automatic grants at any time. Once disabled, new ADF task flows and web pages that you create will not utilize the test-all role and will therefore require that you define the ADF security policy or these resources will remain inaccessible to your testers or end-users, as described in Section 28.4, "Defining ADF Security Access Policies".

To configure ADF Security to use the test-all application role:

  1. In the Application Navigator, select the user interface project that contains the pages you want to secure. Do not select the data model project or any other project.

  2. From the Tools menu, choose Configure ADF Security.

    For information about running the wizard, see Section 28.2, "Choosing ADF Security Authentication and Authorization".

  3. In the Configure ADF Security wizard, select ADF Authentication and Authorization in the ADF Security page.

    If you select one of the other two options, the wizard disables the Automatic Policy Grants page in the wizard. Grants, whether automatic or explicit ones, will be checked by ADF resources only when ADF authorization is enforced.

  4. In the next two pages, select the desired options and click Next until the wizard displays the Automatic Policy Grants page with the No Automatic Grants option selected by default, as shown in Figure 28-11.

    The default option for this page requires you to issue grants to either a developer-defined application role or to a built-in role (anonymous-role and authenticated-role) for all ADF resources.

    Figure 28-11 The Configure ADF Security Wizard Disables the test-all Role By Default

    Default grant option in wizard
  5. In the Automatic Policy Grants page, select one of the two options that will enable automatic View grants to ADF resources, as follows:

    Select Grant to Existing Objects Only when you want JDeveloper to grant View privileges to the test-all application role and you want this policy to apply to all your application's existing ADF task flows and web pages in the user interface project.

    Select Grant to All Objects when you want JDeveloper to grant View privileges to the test-all application role and you want this policy to apply to all ADF task flows and web pages that developers create in the user interface project. Note that the wizard displays the option Grant to New Objects after you run the wizard the first time with the Grant to All Objects option selected.

  6. Complete the remaining pages of the wizard and click Finish.

The test-all role appears in the jazn-data.xml file.

28.3.2 How to Define Application Roles in JDeveloper

The policy store in ADF Security defines grants that establish access rights (or permissions) for specific ADF resources. These access rights are conferred on the authenticated user at runtime through the application role for which the user is defined as a member. Thus, before you can define access policies for ADF resources, you must specify one or more application roles in the jazn-data.xml file. During deployment these application roles will be associated with the enterprise roles that exist. Application roles are specific to the application and therefore provide a level of abstraction to the enterprise roles. You can add application roles to the policy store to distinguish as many levels of security as desired. Each application role will ultimately be associated with a specific set of grants to ADF resources, as described in Section 28.4, "Defining ADF Security Access Policies".

JDeveloper lets you edit the policy store to define application roles using either an overview editor for the ADF security policies or a property editor dialog. You access both editors from the context menu available on the jazn-data.xml file. When you work with property editor dialog, be sure to add the roles to the policy store and not to the identity store (you can also use the property editor to add enterprise security roles to the identity store that the XML security provider defines).

After you have completed the procedure to add an application role, you must associate members with that role, as described in Section 28.3.3, "How to Configure the Identity Store with Test Users in JDeveloper".

To add an application role to the policy store using the property editor dialog:

  1. In the Application Navigator, right-click jazn-data.xml and choose Properties to display the property editor dialog for the XML-based security provider.

  2. In the Edit JPS Identity and Policy Store dialog, create the policy store if one does not yet exist. Click Application Policy Store and click New.

    If the jazn-data.xml file already has application roles defined, then you can add the new role to the existing application policy store, as described in Step 4.

  3. In the Create Application Policy dialog, enter the display name for the policy store and click OK.

  4. In the Edit JPS Identity and Policy Store dialog, expand the application policy store you created and select Application Roles, as shown in Figure 28-12.

    Figure 28-12 Editing the Policy Store Using the Property Editor

    Property editor for jazn-data.xml
  5. In the Application Roles page, click Add to create the application role.

  6. In the Add Application Role dialog, enter the name of the role to add to the policy store.

    For example, you might add the application role fod-users, as shown in Figure 28-13.

    Figure 28-13 Creating the Application Role

    Create application role dialog
  7. Click OK to redisplay the Edit JPS Identity and Policy Store dialog with the new application role, as shown in Figure 28-14.

    Figure 28-14 Displaying the New Application Role in the Property Editor

    Application role definition in jazn-data.xml property editor
  8. In the Edit JPS Identity and Policy Store dialog, click OK to add the application role to the policy store.

    If you examine the source code for the jazn-data.xml file, you will see the application role entry as follows:

    <app-role>
        <name>fod-users</name>
        <display-name/>
        <description/>
        <guid/>
        <class>oracle.security.jps.service.policystore.ApplicationRole</class>
    </app-role>
    

To add an application role to the policy store using the overview editor:

  1. In the Application Navigator, right-click jazn-data.xml and choose Open to display the overview editor for ADF security policies.

  2. In the overview editor, if the ADF resource is a task flow, select the task flow that you want to make a grant for and click the Add Application Role icon in the Granted To Roles column, as shown in Figure 28-15.

    When you just want to add an application role to the policy store, you can select any ADF resource displayed in the overview editor.

    Figure 28-15 Editing the Policy Store Using the Overview Editor

    ADF Security Policies editor
  3. In the Select Role dialog, click the Add Application Role button to create a new application role.

  4. In the Create Application Role dialog, enter the name of the role that will be added to the policy store. Optionally, enter a display name and description.

    For example, you might add the application role fod-users, as shown in Figure 28-16.

    Figure 28-16 Creating the Application Role

    Create application role dialog
  5. Click OK to redisplay the Select Roles dialog with the new application role, as shown in Figure 28-17.

    Figure 28-17 Displaying the New Application Role in Select Roles Dialog

    Select role dialog
  6. In the Select Roles dialog, click OK to add the application role to the policy store.

If you examine the source code for the jazn-data.xml file, you will see an application role definition like this:

<app-role>
    <name>fod-user</name>
    <display-name/>
    <description/>
    <guid/>
    <class>oracle.security.jps.service.policystore.ApplicationRole</class>
</app-role>

28.3.3 How to Configure the Identity Store with Test Users in JDeveloper

You may want to seed the identity store with a temporary set of users to mirror the actual users' experience in your production environment. These test users can log in to the application and be conferred access rights to view the secure ADF resources of your application. To enable the user to view resources, you make grants against application roles rather than the users who are the members of those roles. Therefore, after you seed the identity store with test users, you must associate each user with an application role or they will not have sufficient privileges to view ADF resources.

As a convenience when you use the Configure ADF Security wizard to add the test-all role to the policy store and you only require test users to be authenticated before they are allowed to access the ADF resources, you can add the test user accounts to the identity store and add the built-in application role authenticated-role to the test-all role. All users will automatically have the authenticated-role role once they log in.

You can add test users to application roles directly or as members of the built-in authenticated-role role.

To associate a test user with an application role using the test-all role:

  1. In the Application Navigator, right-click jazn-data.xml and choose Properties to display the property editor dialog for the XML-based security provider.

  2. In the Edit JPS Identity and Policy Store dialog, expand the jazn.com realm and click Users to view the list of users, as shown in Figure 28-18.

    Figure 28-18 Editing the Identity Store Users Using the Property Editor

    User definition in jazn-data.xml property editor
  3. With the Users page displayed, click Add to create the test user.

  4. In the Add User dialog, enter the login name and credentials that the user will be required to enter to become authenticated and click OK.

  5. In the Edit JPS Identity and Policy Store dialog, expand the application policy store and select Application Roles.

  6. In the Application Roles page, select the test-all role to define the members of this role.

    If the test-all role does not display in the Application Roles page, you need to configure Oracle ADF Security, as described in Section 28.3.1, "How to Enable the test-all Application Role in JDeveloper".

  7. In the Application Roles page, click the Member Users tab and shuttle the desired test user to the Selected list, as shown in Figure 28-19.

    Figure 28-19 Adding the User to the test-all Role Using the Property Editor

    test-all role in jazn-data.xml property editor
  8. Alternatively, you can add a system role that you created in the identity store to the test-all role. Click the Member Roles tab and shuttle the desired system role to the Selected list, as shown in Figure 28-20.

    All authenticated members of the system role will have access rights to the ADF resources with a View privilege grant to the test-all role.

    Figure 28-20 Adding a System Role to the test-all Role Using the Property Editor

    ADF Security Policies editor
  9. In the Edit JPS Identity and Policy Store dialog, click OK to update the test-all role in the policy store.

If you examine the source code for the jazn-data.xml file, you will see the test-all role definition with member entries like this:

<app-role>
   <name>test-all</name>
   <guid>FFFF394F68<guid/>
   <display-name>test-all</display-name>
   <description/>
   <class>oracle.security.jps.service.policystore.ApplicationRole</class>
   <members>
       <member>
           <name>sking</name>
           <class>weblogic.security.principal.WLSGroupImpl</class>
       </member>
       <member>
            <name>fod-users</name>
            <class>oracle.security.jps.internal.core.principals.
                                                 JpsXmlEnterpriseRoleImpl</class>
       </member>
   </members>
</app-role>

You can ensure that any authenticated user will have the access rights granted to the test-all application role. You accomplish this by making the built-in authenticated-role role a member of the test-all application role.

To associate any authenticated user with the test-all role:

  1. In the Application Navigator, right-click jazn-data.xml and choose Properties to display the property editor dialog for the XML-based security provider.

  2. In the Edit JPS Identity and Policy Store dialog, expand the jazn.com realm and click Roles to view the list of system roles, as shown in Figure 28-21.

    Figure 28-21 Editing the Identity Store Roles Using the Property Editor

    Role definition in jazn-data.xml property editor
  3. With the Roles page displayed, click Add to create the authenticated-role system role.

  4. In the Add Role dialog, enter the built-in role authenticated-role and click OK.

  5. In the Edit JPS Identity and Policy Store dialog, expand the application policy store and select Application Roles.

  6. In the Application Roles page, click the Member Roles tab and shuttle the authenticated-role role to the Selected list, as shown in Figure 28-22.

    Figure 28-22 Adding the authenticated-role to the test-all Role Using the Property Editor

    test-all role definition in jazn-data.xml property editor
  7. In the Edit JPS Identity and Policy Store dialog, click OK to update the test-all role in the policy store.

If you examine the source code for the jazn-data.xml file, you will see the test-all role definition with an authenticated-role member entry like this:

<app-role>
   <name>test-all</name>
   <display-name>test-all</display-name>
   <description/>
   <guid/>
   <class>oracle.security.jps.service.policystore.ApplicationRole</class>
   <members>
      <member>
         <name>authenticated-role</name>
         <class>oracle.security.jps.internal.core.principals.
                                                JpsXmlEnterpriseRoleImpl</class>
      </member>
   </members>
</app-role>

28.4 Defining ADF Security Access Policies

Authorization relies on a policy store definition that is accessed at runtime and that contains permissions that grant privileges to execute predefined actions, like view, on a specified object. Initially, after you run the Configure ADF Security wizard, the policy store defines no grants. Because ADF resources are secure by default, they will be unavailable to users. You must use JDeveloper to define grants for the resources that you want to permit users to access.

Oracle ADF Security defines the following authorization points for your application's access policies:

Before you can define security policies, your policy store for your application must contain the application roles that you intend to issue grants to. This can be an application role that you define (such as fod-users) or it can be one of the two built-in application roles: authenticated-role or anonymous-role. You can use these application roles to classify users, so that each member of the same role possess the same access rights. As such, the security policy names the application role as the principal of the grant, rather than specific users. For details about defining application roles, see Section 28.3, "Defining Users and Roles for a Fusion Web Application".

Tip:

If you are not ready to define application roles for the users of your application, consider enabling the test-all role in the Configure ADF Security wizard, as described in Section 28.3.1, "How to Enable the test-all Application Role in JDeveloper".

For the view-controller project, you use the overview editor for ADF security policies to secure ADF resources, including ADF task flows and ADF page definitions. In JDeveloper, you open the editor on the jazn-data.xml file from the Application Resources panel in JDeveloper. Note that you can edit the file using two different editors that you select from the file's context menu:

ADF Security relies on the jazn-data.xml file for the policy store whether you are using the XML-based identity store or the LDAP identity store. Thus, with Oracle ADF Security, you define user interface access policies in two steps:

  1. Define an application role for which you will make the ADF resource grant.

    For details about defining application roles, see Section 28.3.2, "How to Define Application Roles in JDeveloper".

  2. Select actions that you want to grant on the Permission that secures the ADF resource.

Together these two steps allow you to define the access policy for authenticated users who belong to an application role with sufficient privileges to access the resource.

For details about granting permissions for row-level security, see Section 28.4.3, "How to Secure Row Data Using ADF Business Components".

28.4.1 How to Grant Permissions on ADF Bounded Task Flows

Certain Oracle ADF resources are security-aware, meaning predefined resource-specific permissions exist that a developer can grant. Among these resources are ADF task flow definitions that JDeveloper creates for you when you use the ADF task flow diagrammer to create a task flow. By defining an access policy for the task flow definition, you can control the user's ability to view the web pages of the entire task flow.

Objects within the bounded task flow inherit the task flow's access policy. For example, authorization to an ADF bounded task flow defaults authorization for any pages and other ADF bounded task flows contained within it. You cannot override the default authorizations at the task flow's page level. For cases where you need to issue grants to individual web pages that are not part of a task flow, see Section 28.4.2, "How to Grant Permissions on Individual Web Pages Using ADF Page Definitions".

The access policy represents a set of privileges required to perform a set of operations for a task flow. If authorization is given to view the task flow, the task flow can also be executed. If authorization is not given, a runtime exception will be received. The calling task flow can handle the exception within its Exception Handler activity.

ADF unbounded task flows are not securable.

You define the access policy for an ADF bounded task flow by selecting the task flow definition name in the overview editor for ADF security policies, as shown in Figure 28-23. The selections you make will appear as metadata in the policy store section of the jazn-data.xml file. This metadata defines a permission target for which you have issued grants to authorize the members of a specific application role.

Figure 28-23 Grant Made to Task Flow in Overview Editor

Task flow grants in ADF policy editor

The list of available actions displayed by the overview editor is defined by the task flow permission class (oracle.adf.controller.security.TaskFlowPermission). The permission class maps these actions to the operations supported by the task flow. Table 28-4 shows the grantable actions of ADF bounded task flows.

Table 28-4 Secured Actions of ADF Bounded Task Flows

Grantable Action Affect on the User Interface

View

Read and execute a bounded task flow.

This is the only operation that the task flow supports in this release.


To define a grant for the task flow security policy, use the Task Flows page of the overview editor that you open for the jazn-data.xml file.

To define a permission grant on an ADF bounded task flow:

  1. In the Application Resources panel, double-click the jazn-data.xml file located in the Descriptors/META-INF node.

  2. In the overview editor, select the Task Flows tab.

    The Task Flows page displays all the task flows that your application defines. Task flows are defined by adfc-config.xml files that appear in the Web Content/Page Flows node of the user interface project.

  3. In the Task Flows column, select the task flow for which you want to grant access rights.

    Use the search field to limit the task flows displayed in the overview editor.

  4. In the Granted to Roles column, click the Add Application Role button and select the application role from the Select Role dialog that you want to make a grantee of the permission.

    The Select Roles dialog displays application roles from the jazn-data.xml file. If the dialog displays no application roles, you must define at least one application role, as described in Section 28.3.2, "How to Define Application Roles in JDeveloper".

  5. In the Actions column, select the action you want to grant for the role so that it appears enabled.

    The TaskFlowPermission class defines task flow--specific actions that it maps to the task flow's operations, as described in Table 28-4. For example, to grant View permission to the user role, select it as shown in Figure 28-24.

    Figure 28-24 Grant Made to the User Role for an ADF Task Flow Definition

    Task flow grant in ADF policy editor
  6. You can repeat these steps to make additional grants as desired.

    The same task flow definition can have multiple grants made for different application roles. The grants appear in the policy store definition of the jazn-data.xml file.

28.4.2 How to Grant Permissions on Individual Web Pages Using ADF Page Definitions

Certain Oracle ADF resources are security-aware, meaning predefined resource-specific permissions exist that a developer can grant. Among these resources are ADF page definitions that JDeveloper creates for you when you work with the ADF data controls. By defining an access policy for the page definition, you can control the user's ability to view the web page itself. There is a one-to-one relationship between the page definition file and the web page it secures.

You can issue grants for an existing ADF page definition. JDeveloper creates the page definition file for you when you use ADF data controls to add ADF Faces components to the web page. Alternatively, when your web page does not need to use ADF data controls, for example to databind ADF Faces components, you can create the page definition file yourself by right-clicking the file and choosing Go to Page Definition.

There is a one-to-one relationship between the page definition file and the web page it secures.

You define the access policy for an ADF page definition by selecting the page definition name in the overview editor for ADF security policies, as shown in Figure 28-25. The selections you make will appear as metadata in the policy store section of the jazn-data.xml file. This metadata defines a permission target for which you have issued grants to authorize the members of a specific application role.

Figure 28-25 Grant Made to test-all Role for an ADF Page Definition

Page definition grant in ADF policy editor

The list of available actions displayed by the overview editor is defined by the region permission class (oracle.adf.share.security.authorization.RegionPermission). The permission class maps these actions to the operations supported by the ADF page definition for the web page. Table 28-5 shows the grantable actions of the ADF page definition.

Table 28-5 Securable Actions of ADF Page Definitions

Grantable Action Affect on the User Interface

View

View the page.

This is the only operation that the page definition supports in this release.


To define a grant for the page definition security policy, use the Web Pages page of the overview editor that you open for the jazn-data.xml file.

To define a permission grant on an ADF page flow:

  1. In the Application Resources panel, double-click the jazn-data.xml file located in the Descriptors/META-INF folder.

  2. In the overview editor, select the Web Pages tab.

    The Web Pages page of the overview editor displays all web pages that have an associated ADF page definition. This includes any web page that uses ADF data bindings or any web page for which you created an empty page definition. Page definitions are defined by PageDef.xml files that appear in the Application Sources node of the user interface project.

  3. In the Web Page Definition column, select the web page and associated page definition for which you want to grant access rights.

    The web page definition may display the lock symbol if you have not already made the page accessible to an application role. For example, the page account_addressDetails.jsff shown in Figure 28-26 is still secure since no grant has been made.

    Use the search field to limit the page definitions displayed in the overview editor. For example, a search on the word account would display only the web pages that begin with the word account, as shown in Figure 28-26.

    Figure 28-26 Limiting Web Pages Displayed in the Overview Editor

    Searching for a web page in ADF policy editor
  4. In the Granted to Roles column, click the Add Application Role icon and select the application role from the Select Roles dialog that you want to make a grantee of the permission.

    The Select Roles dialog displays application roles from the jazn-data.xml file. You can define an application role or use one of the built-in application roles, as described in Section 28.3.2, "How to Define Application Roles in JDeveloper".

  5. In the Actions column, select the action you want to grant for the role so that it appears enabled.

    The RegionPermission class defines page definition--specific actions that it maps to the page's operations, as described in Table 28-5. For example, to grant View permission to the fod-users role, select it as shown in Figure 28-27.

    Figure 28-27 Granting to the fod-users Role for an ADF Page Definition

    Page definition grant in ADF policy editor
  6. You can repeat these steps to make additional grants as desired.

    The same page definition can have multiple grants made for different application roles. The grants appear in the policy store definition of the jazn-data.xml file.

28.4.3 How to Secure Row Data Using ADF Business Components

Oracle ADF entity objects in the model project are security-aware, meaning predefined resource-specific permissions exist that a developer can grant. Additionally, you can secure just the individual attributes of entity objects.

Entity objects that you secure restrict users from updating data displayed by any web page that renders a UI component bound by an ADF binding to the data accessed by the secured entity object. Additionally, when you secure an entity object, you effectively secure any view object in the data model project that relies on that entity object. As such, entity objects that you secure define an even broader access policy that applies to all UI components bound to this set of view objects. For details about entity-based view objects, see Section 5.2, "Populating View Object Rows from a Single Database Table".

28.4.3.1 Defining a Permission on ADF Business Component Entity Objects

You can secure operations of the entity objects or their individual attributes.

In the data model project, you use the business component's overview editor to define a permission map for the specific actions allowed by the business component. The metadata consists of a permission class, permission name, and a set of actions mapped to binding operations.

The list of available operations displayed by the overview editor is defined by the entity object permission class (oracle.adf.share.security.authorization.EntityPermission). The permission class maps the operations supported by the entity object to actions. Table 28-6 shows the securable operations of the entity object.

Table 28-6 Securable Operations of Oracle ADF Business Components

ADF Component Securable Operation Expected Mapped Action Corresponding Implementation

ADF Business Components entity objects

read

Read

View the rows of a result set that has been restricted by a WHERE clause fragment.

 

removeCurrentRow

Delete

Delete a row from the bound collection.

 

update

Update

Update any attribute of the bound collection.

ADF Business Components attributes of entity objects

update

Update

Update a specific attribute of the bound collection.


To secure all row-level data that the entity object accesses, use the overview editor for the business component.

To secure an operation on an entity object:

  1. In the data model project displayed in the Application Navigator, double-click the entity object that you want to secure.

  2. In the General page of the overview editor, expand the Security section.

    The Security section displays the securable operations that the EntityPermission class defines. The class maps the entity object--specific actions to the entity object's operations, as described in Table 28-6.

  3. In the Enabled column, select the operations you want to secure for the entity object.

    For example, to enable read permission, select it as shown in Figure 28-28.

    Figure 28-28 Permission Enabled on read Operation for an ADF Entity Object

    Read operation enabled for entity object

    The permissions appear in the XML definition of the entity object.

To secure individual columns of data that the entity object accesses, use the attribute page of the overview editor for the business component.

To secure an operation on an entity object attribute:

  1. In the data model project displayed in the Application Navigator, double-click the entity object that defines the attribute you want to secure.

  2. In the Attributes page of the overview editor, select the desired attribute, and expand the Security section.

    The Security section displays the securable operations that the EntityAttributePermission class defines. The class maps the entity object--specific actions to the entity object's operations, as described in Table 28-6.

  3. In the Enabled column, select the operation you want to secure for the entity object attribute.

    For example, to enable update permission, select it as shown in Figure 28-29.

    Figure 28-29 Permission Enabled on update Operation for an ADF Entity Object Attribute

    Update operation enabled on entity object

    The permission map appears in the XML definition of the entity object.

28.4.3.2 Granting Permissions on ADF Business Components

Once a permission target is configured, any data that derives from entity objects or their attributes remain unsecured until you explicitly define access rights for the entity object's permission target.

To define the access policy for an existing business component permission target, use the Edit Authorization dialog.

To define the access policy for an entity object:

  1. In the data model project displayed in the Application Navigator, locate the entity object and select it.

  2. In the Structure window for the selected entity object or entity object attribute, right-click and choose Edit Authorization.

    The Edit Authorization dialog displays the available actions of the entity object (or attribute), as described in Table 28-6. The dialog also displays the application roles from the jazn-data.xml policy store. The built-in application roles anonymous-role and authenticated-role will appear with application roles that the application developer created.

  3. In the dialog, select the action that you want to grant to a specific application role.

    For example, to grant Update and Delete privileges to the fod-users application role, select those actions, as shown in Figure 28-30.

    The grant to the application role appears in the jazn-data.xml file.

Figure 28-30 Defining the Access Policy for an Entity Object

Edit Authorization dialog for entity object

28.4.4 What Happens When You Define a Security Policy for ADF Resources

The overview editor for the jazn-data.xml file exposes application-level roles that are defined in the policy store (the jazn-data.xml file located in the /src/META-INF node relative to the web application workspace.) and displays the actions that are defined against a specific component type. To implement the security policy, you select the desired action against one or more of the displayed roles.

Note:

In this release, policy information in the JAAS policy store is scoped by application. This scoping allows two applications to refer to the same permission target, without producing unintentional results. It is no longer necessary to name application resources to impose application scoping of the policy information.

The overview editor writes the permission information to the policy store. The policy defines a permission type, the resource that is secured, the actions that can be performed against that resource, and to whom that policy is being assigned or granted. The policy is defined by a grant, which contains both a grantee and one or more permissions.

A grantee defines to whom the policy is applied. Example 28-1 shows how grants are defined in the jazn-data.xml file.

Example 28-1 Grants in the jazn-data.xml file

<jazn-policy>
  <grant>
    <grantee>
      <principals>
        <principal>
          <class>oracle.security.jps.service.policystore.ApplicationRole</class>
          <name>fod-user</name>
        </principal>
      </principals>
    </grantee>
    <permissions>
      <permission>
         <class>oracle.adf.controller.security.TaskFlowPermission</class>
         <name>/WEB-INF/checkout-task-flow.xml#checkout-task-flow</name>
         <actions>view</actions>
      </permission>
    <permissions>
      <permission>
         <class>oracle.adf.share.security.authorization.RegionPermission</class>
         <name>oracle.fodemo.storefront.pageDefs.homePageDef</name>
         <actions>view</actions>
      </permission>
      . . .
    </permissions>
    ...
  </grant>
  ...
<jazn-policy/>

In this grant, the role principal fod-user has been assigned view permission on the checkout-task-flow and the home web page with the homePageDef page definition. For the web page, notice that permission has been specified against the homePageDef page definition associated with the home page.

When authorization is enabled for Oracle ADF Security, JAAS authorization checks are performed on all ADF bounded task flows and all web pages defined by an ADF page definition.

The authorization check for a task flow determines whether the user has the required permission (typically, view permission). If the user is not authorized, an exception is thrown and ADF controller passes control to a designated exception handler. This designated exception handler should not be invoked inside the secured task flow, as this could result in a security violation. Instead, you can invoke the exception handler for secure task flows somewhere in the task flow's calling stack (see Section 17.4, "Handling Exceptions" for more information). If the user is authorized, then the task flow is entered.

28.4.5 What You May Need to Know About ADF Resource Grants

Grants that you make for ADF resources are standard JAAS Permissions. The web container will utilize the grants when ADF Security is enabled to allow authorization. In the authorization mode, ADF Security uses fine-grained authorization, implemented with JAAS Permissions to perform security checks for access rights to pages. The ADF Security enforcement logic checks to see whether the user, represented by the JAAS Subject, has the right permissions to access the resource.

The Subject contains the user's Principals, which include a user principal that contains their name (could be anonymous, before logging on, or some user name after logging on), and their list of role principals, which would include anonymous-role and some number of other roles that are obtained from the policy and identity stores. The Principal is created to represent all of the user's memberships in identity store roles and application roles in the policy store.

In turn, each of these roles may have multiple Permissions associated with them. These are the permission grants that are assigned through the overview editor you use on the jazn-data.xml file to indicate which roles have access to which pages. The grants are expected to be made against application roles and not directly to identity store roles.

During deployment, you will need to edit the application roles in the policy store to reflect who from the identity store belongs to each role. You can update the roles with members that are users or identity store roles.

Then at runtime, whether the current user has view permission on the page they are trying to access will be determined by the task flow controller or by the ADF Model when the user accesses a web page outside of a task flow and that page is associated with an ADF page definition. Oracle Security Platform then checks to see whether the Subject contains the roles that have the corresponding Permissions needed to access the page.

28.4.6 How to Use Regular Expressions to Define Policies on Groups of Resources

Consider Example 28-2, in which each method name starts with method_.

Example 28-2 Method Permission Defined in the jazn-data.xml File

<principal>
 <class>oracle.security.jps.service.policystore.ApplicationRole</class>
 <name>anonymous-role</name>
</principal>

<permission>
   <class oracle.adf.share.security.authorization.MethodPermission </class>
   <name>method_1</name>
   <actions>invoke</actions>
</permission>

<permission>
   <class> oracle.adf.share.security.authorization.MethodPermission </class>
   <name>method_2</name>
   <actions>invoke</actions>
</permission>

<permission>
   <class> oracle.adf.share.security.authorization.MethodPermission </class>
   <name>method_3</name>
   <actions>invoke</actions>
</permission>

<permission>
   <class> oracle.adf.share.security.authorization.MethodPermission </class>
   <name>method_4</name>
   <actions>invoke</actions>
</permission>
...

As there are potentially many more individual methods for which the anonymous-role role must be granted the invoke permission, you can greatly simplify the policy definition by replacing the name with a regular expression that represents the set of methods to which anonymous-role is granted the invoke permission.

For example, the previous listing of permissions could be replaced with a single permission, as shown in Example 28-3.

Example 28-3 Using Regular Expressions to Define Permission for Methods

<grant>
   <grantee>
      <principals>
         <principal>
            <class>oracle.security.jps.service.policystore.ApplicationRole</class>
            <name>anonymous-role</name>
         </principal>
      </principals>
   </grantee>
   <permissions>
      <permission>
         <class oracle.adf.share.security.authorization.MethodPermission </class>
         <name>method_*</name>
         <actions>invoke</actions>
      </permission>
   </permissions>
</grant>

As the overview editor for the jazn-data.xml file does not support the use of regular expressions in the user interface, you must edit the file directly. Do not edit the policy store of the system-jazn-data.xml file directly. Instead, add grants using regular expressions to the jazn-data.xml file. These grants will then be merged to the policy store when you run or deploy the application.

The use of more complex regular expressions enables you to define business rules in the policy, thus creating a very targeted set of permissions. For example, you can grant the invoke permission on all methods and deny specific methods at the same time by defining a exclusion set in your regular expression. Example 28-4 shows how the invoke permission is granted to the anonymous-role role for all methods except those for which the method name starts with delete.

Example 28-4 Granting the Invoke Permission to the anonymous-role Principal for Specific Methods

<grant>
   <grantee>
      <principals>
         <principal>
            <class>oracle.security.jps.service.policystore.ApplicationRole</class>
            <name>anonymous-role</name>
         </principal>
      </principals>
   </grantee>
   <permissions>
      <permission>
         <class>oracle.adf.share.security.authorization.MethodPermission</class>
         <name>[^(delete)].*</name>
         <actions>invoke</actions>
      </permission>
   </permissions>
</grant>

Table 28-7 shows some of the basic regular expression metacharacters that you can use in your policy definitions.

Table 28-7 Description of Metacharacters

Metacharacter Description

[abc]

a, b, or c (included in list)

[^abc]

Any character except a, b, or c (negation)

[a-zA-Z]

a to z or A to Z, inclusive (range)

[a-d[m-p]]

a to d, or m to p ~= [a-dm-p](union)

[a-z&&[def]]

d, e, or f (intersection)

[a-z&&[^bc]]

a through z, without b and c: [ad-z] (subtraction)

[a-z&&[^m-p]]

a through z, and not m through p

*

Any number of arbitrary characters


28.5 Handling User Authentication in a Fusion Web Application

Oracle ADF Security allows for implicit and explicit authentication:

On the first access to a page, if there is no Subject defined, one is created containing the anonymous user principal and the anonymous-role principal.

With this role principal, the user can access any page on which no web.xml security constraint is defined for the anonymous-role principal and on which the view permission has been granted.

For a discussion on how ADF Security lets you grant privileges to the anonymous user, see Section 28.5.5, "What You May Need to Know About the Anonymous User".

28.5.1 How to Create a Login Component for Your Application

You can create a standard login component that can be added to any page in your application to enable users to authenticate or subsequently log off. This component keeps track of the authenticated state of the user and returns the appropriate login or logout URLs and icons. Furthermore, it keeps track of the name of the current user (anonymous or the name of the logged-in user). Hence, using this login component provide you with a single, consistent object. Figure 28-31 shows a login icon added to the global menu facet of the welcome page in a Fusion web application.

Figure 28-31 Login Icon on the Page

Login icon on the page

The login component will redirect users back to the current page once they are authenticated.

Note:

You may want to alter the component's code to redirect to a welcome page if the current page is not publicly accessible.

To create a login component:

  1. In the Applications Navigator, expand the WEB-INF node in the user interface project and double-click the faces-config.xml file.

  2. In the Structure window, select the Overview tab.

  3. Right-click Managed Beans and choose Insert managed-bean.

  4. In the Create Managed Bean dialog, specify authNLink for the name, view.util.AuthNLink for the class, and set the scope to session, as shown in Figure 28-32. Select Generate Class If It Does Not Exist, if it is not already selected.

    Figure 28-32 Create Managed Bean Dialog

    Create Managed Bean dialog
  5. Click OK and open the view.util.AuthNLink.java file under the application sources.

  6. Add the following private variables to the managed bean definition, as shown in the following example:

    public class AuthNLink {
        private boolean _authenticated = false;
        private String _label = null;
        private String _icon = null;
        private String _url = null;
        private String _currentUser = null;
    
  7. From the Source dropdown list, select Generate Accessors.

  8. Expand each node and check the getter methods (the ones that start with is and get), as shown in Figure 28-33.

    Figure 28-33 Generate Accessors Dialog

    Generate Accessors dialog
  9. Define the methods, as shown in Example 28-5.

    Note:

    Import the ADFContext and FacesContext when prompted, by pressing ALT-Enter with the cursor over the appropriate line.

    This example has fixed English labels. To internationalize the code, you can define these strings in a resource bundle. For more information about internationalization, see the "Internationalizing and Localizing Pages" chapter in the Oracle Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework.

    Example 28-5 Login Component Code

    // ============ User's Authenticated Status =============
        public boolean isAuthenticated() {
         _authenticated =
    ADFContext.getCurrent().getSecurityContext().isAuthenticated();
        return _authenticated;
        }
        // ================== Link Label =======================
         public String getLabel()
         {
          // toggle link text based on authenticated state of the user.
          if (isAuthenticated())
             { _label = "Click here to log in"; }
          else 
             { _label = " Click here to log out";  }
           return _label;
         }
        // ================== Link Icon =======================
        public String getIcon() {
            // toggle icon based on authenticated state of the user.   
            if (isAuthenticated())
                _icon = "logout.gif";
            else
                _icon = "login.gif";
            return (_icon);
        }
        // ================== Link URL =======================
         public String getUrl() 
         {
           String currentPage = null;
           String urlBaseRef  = null;
           String urlBaseRef2 = null;
           FacesContext fctx = FacesContext.getCurrentInstance();
                currentPage = "/faces" + fctx.getViewRoot().getViewId();
                        if (isAuthenticated()) 
            _url = "/adfAuthentication?logout=true&end_url=" + currentPage;
           else 
            _url = "/adfAuthentication?success_url=" + currentPage;
           return (_url);
         }
        // ============ Current User's Name/PrincipalName =============
         public String getCurrentUser() {
          _currentUser = ADFContext.getCurrent().getSecurityContext().getUserName(); 
             return _currentUser;
         }
    

    In this code, the component uses the isAuthenticated method of the Oracle ADF security context to determine whether the user is currently authenticated. The component also modifies the link text, the link text URL, and the associated icon accordingly.

  10. Copy your login and logout image files (GIF, JPG, or PNG files) to the public_html directory of your project.

    Note:

    The images used should reference the appropriate skin image if your application uses skins. For more information about skins, see the "Customizing the Appearance Using Styles and Skins" chapter in the Oracle Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework.

How to Add the Login Component to a Page

To add a login component to a page:

  1. In the Application Navigator, double-click the page.

  2. From the Component Palette, select ADF Faces Core.

  3. Select a menuButtons component and drag it onto the page.

    Note:

    If you are using an Oracle ADF PanelPage component to lay out the page, you should place the global navigation items such as the login link in the menuGlobal facet. This will place the link in a consistent location on the page (by default, this is the top-right corner of the page).
  4. Select a goMenuItem and drag it onto the MenuButtons component.

  5. In the Property Inspector, set the Text, Destination, and Icon properties of the goMenuItem to the values provided in the following table:

    Property Value
    Text #{authNLink.label}
    Destination #{authNLink.url}
    Icon #{authNLink.icon}

    To set these properties, navigate to the authNLink node under JSF Managed Beans in the Binding to Data dialog and set the values provided in the table. You can access the Bind to Data dialog in either of the following ways:

    • Right-click goMenuItem in the Structure pane and click Properties. In the Properties dialog, click the Bind to Data icon next to the property.

    • In the Property Inspector, click the Bind to Data icon in the filed next to the property.

    Figure 28-34 and Figure 28-35 show the settings for the Text and Destination properties in the Bind to Data dialog.

    Figure 28-34 Bind to Data Dialog for the Text Property

    Bind to Data dialog

    Figure 28-35 Bind to Data Dialog for the Destination Property

    Bind to Data dialog box for the Destination property
  6. As the login component keeps track of the current user, you can also display the user's name on your page. To do this, from the Component Palette, select ADF Faces Core and drag an OutputFormatted component onto the page.

  7. Set the value of the OutputFormatted to The Current User is <i>#{authNLink.currentUser}</i>.

  8. Save the page and run it. It will look similar to Figure 28-36.

    Figure 28-36 Page with a Log In Link

    Page with a log in link

    Note:

    To enforce security in your application, you must first perform the steps described in Section 28.2, "Choosing ADF Security Authentication and Authorization" and Section 28.4, "Defining ADF Security Access Policies". You must, at a minimum, grant view privileges to the anonymous role.
  9. Click Log in and log in as a user with the appropriate credentials. Once logged in, the page will look similar to Figure 28-37.

    Figure 28-37 Page with a Log Out Link

    Page with a log out link

28.5.2 How to Add a Login Component to a Web Page

You can add the login component to any page in your application.

To add the login component to a page:

  1. In the Application Navigator, double-click the page.

  2. From the Component Palette, select ADF Faces Core.

  3. Select a menuButtons component and drag it onto the page.

    Note:

    If you are using an Oracle ADF PanelPage component to lay out the page, you should place global navigation items such as the login link in the menuGlobal facet. This will place the link in a consistent location on the page (by default, this is the top-right corner of the page).
  4. Select a goMenuItem and drag it onto the MenuButtons component.

  5. In the Property Inspector, set the Text, Destination, and Icon properties of the goMenuItem to the values provided in the following table:

    Property Value
    Text #{authNLink.label}
    Destination #{authNLink.url}
    Icon #{authNLink.icon}

    To set these properties, navigate to the authNLink node under JSF Managed Beans in the Bind to Data dialog and set the values provided in the table. You can access the Bind to Data dialog in either of the following ways:

    • Right-click goMenuItem in the Structure window and click Properties. In the Properties dialog, click the Bind to Data icon next to the property.

    • In the Property Inspector, click the Bind to Data icon in the field next to the property.

    Figure 28-34 and Figure 28-35 show the settings for the Text and Destination properties in the Bind to Data dialog.

    Figure 28-38 Bind to Data Dialog for the Text Property

    Bind to Data dialog

    Figure 28-39 Bind to Data Dialog for the Destination Property

    Bind to Data dialog box for the Destination property
  6. Because the login component keeps track of the current user, you can also display the user's name on your page. To do this, from the Component Palette, select ADF Faces Core and drag an OutputFormatted component onto the page.

  7. Set the value of the OutputFormatted to The Current User is <i>#{authNLink.currentUser}</i>.

  8. Save the page and run it. It will look similar to Figure 28-36.

    Figure 28-40 Page with a Log In Link

    Page with a log in link

    Note:

    To enforce security in your application, you must first perform the steps described in Section 28.2, "Choosing ADF Security Authentication and Authorization" and Section 28.4, "Defining ADF Security Access Policies". You must, at a minimum, grant View privileges to the anonymous role.
  9. Click Log in and log in as a user with the appropriate credentials. Once you are logged in, the page will look similar to Figure 28-37.

    Figure 28-41 Page with a Log Out Link

    Page with a log out link

28.5.3 How to Create a Login Page for Your Application

Web applications typically have a notion of public pages and allow for explicit as well as implicit authentication. This means that users can log in to the application by clicking the login link before they navigate to secured content, or they can navigate to a secured page, which will redirect them to the login page for the application. For more information about implicit and explicit authentication, see Section 28.2.8, "What Happens at Runtime: How Oracle ADF Security Handles Authentication". Figure 28-42 shows a sample login page. The addition of portlets to the login page allows the login page itself to be indistinguishable from the other pages in your Fusion web application.

Note:

This section discusses creating an Oracle ADF Faces-based login page that enables you to include customizable components and portlets. However, if adding these components is not a requirement, then a simple JSP or HTML login page can be also used.

Container-based authentication relies on the j_SecurityCheck method within the container's security model. Both the Oracle ADF Faces--based login page and the simplified login pages use this method to enforce authentication.

For details about generating a simple login page when running the Configure ADF Security wizard, see Section 28.2, "Choosing ADF Security Authentication and Authorization".

Figure 28-42 Login Page

Login page

28.5.3.1 Creating an Oracle ADF Faces--Based Login Page

To create the Oracle ADF Faces-based login page:

  1. In the Application Navigator, under the user interface project, right-click your application and choose New.

  2. In the New Gallery dialog, expand the Web Tier node, select JSF and in the Items list select JSF, then click OK.

  3. In the Create JSF Page dialog, select Create as XML Document (*.jspx).

  4. In the File Name field, specify a name for your login page.

  5. Expand Page Implementation to display the component binding options.

  6. Select Automatically Expose UI Components in a New Managed Bean.

  7. Click OK.

  8. Save the page.

  9. From the Component Palette, select Customizable Components Core.

  10. Select the PanelCustomizable component and drag it onto the Structure window above the h:form node.

  11. In the Confirm Add Form Element dialog, click No. You will be creating a custom HTML form in PanelBox instead.

  12. In the Property Inspector, set the layout of Panel Customizable to Horizontal.

  13. In the Structure window, drag the h:form node onto the cust:panelCustomizable node, as shown in Figure 28-43.

    Figure 28-43 h:form Node

    h:form node in Structure pane
  14. Open the Component Palette, select ADF Faces Core and drag a PanelBox above the h:form tag in the Structure window.Set the Text property of the PanelBox to Login, as shown in Figure 28-44.

    Figure 28-44 Text Property of the panelBox

    Text property of the panelBox component set to Login
  15. Select an OutputText component and drag it onto the PanelBox component.

  16. Save the page.

You can now use a backing bean to inject the appropriate login form into this PanelBox area.

28.5.3.2 Creating Login Code for the Backing Bean

After you create the login page as an Oracle ADF Faces page, you cannot just add the login form using form elements from the Component Palette. This would cause the form elements to be serialized and remapped at runtime by the Oracle ADF Faces lifecycle. Instead, you can inject the HTML for the login form at runtime by including it in the backing bean and dynamically showing this at runtime.

To include the HTML code in a backing bean and to reference the HTML login form in the login page:

  1. In the Applications Navigator, expand the Application Resources node and open the pageName.java backing bean.

  2. To define the bean _loginFormBlock, create a new attribute by adding the following in the declaration section of the ADFLogin.java file:

    private String _loginFormBlock;
    
  3. Add the get method for this attribute right before the closing brace (}) in this Java class, as shown in Example 28-6.

    Example 28-6 LoginFormBlock Code That Injects the Login Form into the Login Page

    public String getLoginFormBlock() 
    {
        String htmlBlock      = null;
        String userNameLabel  = "Username";
        String passwordLabel  = "Password";
        String buttonLabel    = "Login";
        
        
        htmlBlock = "\n\n" +
         "<!-- === Login Form Block Generated in Backing Bean ==== -->\n" +
         "<form name=\"LoginForm\" id=\"LoginForm\" \n" +
         "      action=\"j_security_check\" method=\"POST\" >\n" +
         " <table cellspacing=\"5\" cellpadding=\"0\" border=\"0\" width=\"50%\">\n" +
         " <tr>\n" +
         "  <td nowrap>" + userNameLabel + "</td>\n" +
         "  <td nowrap><input type=\"text\" name=\"j_username\"/></td>\n" +
         " </tr>\n" +
         " <tr>\n" +
         "  <td nowrap>" + passwordLabel + "</td>\n" +
         "  <td nowrap><input type=\"password\" name=\"j_password\"/></td> \n" +
         " </tr>\n" +
         " <tr>\n" +
         "  <td><input type=\"submit\" value=\"" + buttonLabel + "\"/></td> \n" + 
         " </tr>\n" +
         " </table>\n" +
         "</form>\n" +
         "<!-- ================================================= -->\n\n" ;
        _loginFormBlock = htmlBlock;
        return (_loginFormBlock);
        }
    

    This code returns the entire login block as a simple output string (simplifying the need for <verbatim> tags).

  4. Save the Java file.

  5. In the Property Inspector, set the value of the previously created outputText object to the following value of the loginFormBlock attribute, as shown in Figure 28-45:

    #{backing_ADFLogin.loginFormBlock}
    

    Figure 28-45 loginFormBlock Attribute

    loginFormBlock attribute of the outputText object

    This will result in the full sting appearing as "Text" within the page, as shown in Figure 28-46.

    Figure 28-46 Login Form Block Generated in the Backing Bean

    Login Form Block generated in the backing bean
  6. In the Property Inspector, set the Escape property of the outputText object to False to render the string as static HTML as shown in Figure 28-47.

    Figure 28-47 HTML Login Form

    HTML login form
  7. Save the file.

28.5.3.3 Configuring the web.xml File for an Oracle ADF Faces-Based Login Page

Because the login page is called directly from the container, it is not part of the Oracle ADF Faces navigation process. As such, you must force a call to the Oracle ADF Faces servlet when calling the login page.

You can accomplish this in the Authentication Type page of the Configure ADF Security wizard when you configure ADF Security or in the web.xml file directly. If you have already run the Configure ADF Security wizard, you can use the following procedure to confirm that the web.xml file has been updated as described.

To reference an login page as part of the ADF Faces lifecycle:

  1. In the Application Navigator, expand the WEB-INF node, right-click web.xml and choose Properties.

  2. In the Web Application Deployment Descriptor dialog, select Login Configuration.

  3. In the Login Configuration page, set the login page to include a reference to the Oracle ADF Faces servlet such that the login page can be part of the Oracle ADF Faces lifecycle /faces/ADFlogin.jspx page, as shown in Figure 28-48.

    Figure 28-48 Adding a Reference to the Faces Servlet in the Login Configuration

    Form Based Authentication section
  4. Click OK.

28.5.3.4 Ensuring That the Login Page Is Public

Because the application is secured by Oracle ADF Security, all web pages defined within bounded task flows are secured or any web page defined by an ADF page definition. Since all users must be allowed to log on, the login page should remain publicly accessible. No further steps are required to ensure that the container will always redirect to the defined authentication point before allowing access to the page (which in this case is the authentication page).

Use only ASCII characters to name applications and projects when you enable ADF Security. Login will fail when either the application name or the project name contains multibyte characters.

28.5.4 How to Create a Public Welcome Page for Your Application

Because web applications are generally secured, there is always a need for a starting point or home page for unauthenticated users. To create this public welcome page, you create an Oracle ADF Faces page to act as the entry point for the application, which contains links to other pages within the application. However, only links to public pages should be rendered to unauthenticated users and, conversely, links to secured pages should be rendered only after the user has logged in and has the appropriate privileges to view the target page.

Note:

When you run the Configure ADF Security wizard, you can optionally allow the wizard to generate a default welcome page for your application. For details about running the wizard, see Section 28.2, "Choosing ADF Security Authentication and Authorization".

28.5.4.1 Ensuring That the Welcome Page Is Public

After you have created a regular Oracle ADF Faces page, the page will, by default, be public and accessible by unauthenticated users. If, however, you have associated the welcome page with an ADF resource, for example, by dropping databound ADF Faces components into the welcome page using the Data Controls Panel, then ADF Security will secure the page by default. You can make any ADF resource publicly accessible using the overview editor for ADF security policies by granting a View privilege on the resource to the provided anonymous-role. For details about the anonymous-role see, Section 28.5.5, "What You May Need to Know About the Anonymous User".

28.5.4.2 Adding Login and Logout Links

You can add login and logout links to your public welcome page so that users can explicitly log in and out while they are in the application. While Java EE container-managed security supports the concept of authentication when accessing a secured resource, there is no standard way to log out and stay within a secured application. However, it is a common practice in web applications to allow the user to stay on the same page if that page is public or to return the user to the welcome page if that page is secured. While adding the login and logout links to each page would let the user end their login session anywhere within the application (and return to the welcome page), having these links on the welcome page enables users to explicitly authenticate on entering the application.

To add the login and logout links, you must add a login component to your application and then add the login and logout links to your page, as described in Section 28.5.1, "How to Create a Login Component for Your Application".

28.5.4.3 Hiding Links to Secured Pages

Since an anonymous user should not have access to any secured pages, any navigation component on the welcome page that points to a secured page should be hidden from view based on the following two criteria:

  • Is the user authenticated with a known user identity?

  • Does the specified user identity have permission to view the target?

If either of these criteria has not been met, the rendered attribute of any navigation component on a public page that points to a secured resource must have its rendered property set to false, thus hiding it from the anonymous user. To enforce these rules within your welcome page, see section Section 28.6, "Performing Authorization Checks in a Fusion Web Application".

28.5.5 What You May Need to Know About the Anonymous User

It is a common requirement that some web pages should be available to all users regardless of their specific access privileges. For example, the home page should be seen by all visitors to the site, while a corporate site should be available only to those who have identified themselves through authentication.

In both cases, the page may be considered public, because the ability to view the page is not defined by the users' specific permissions. Rather, the difference is whether the user is anonymous or a known identity.

This use of public is different from traditional Java EE security, which does not let you distinguish between completely unsecured content (security has not been enabled) and public content.

In the Oracle ADF Security model, you explicitly differentiate between the absence of security and public access to content by granting access privileges to the anonymous-role principal. The anonymous-role is a role that encompasses both known and anonymous users thus, permission granted to anonymous-role allows access to a resource by unauthenticated users, for example, guest users. To provide access to authenticated users only, the policy must be defined for the authenticated-role principal. For details about granting to these built-in roles, see Section 28.3.3, "How to Configure the Identity Store with Test Users in JDeveloper".

28.6 Performing Authorization Checks in a Fusion Web Application

While the existence of a policy will prevent unauthorized users from accessing a secured resource, their attempt to access the resource would result in a security exception. Good security practice dictates that users should not be aware of resources and capabilities to which they do not have access.

For example, if a user does not have permission to view an administrative page, then all navigation components that point to that page should be dynamically removed for that user. Similarly, if a user does not have permission to begin a new task flow, a button that the page displays to invoke that task flow should not be visible to the user.

While the application must first evaluate the policy to determine whether the user has the appropriate permission required by the target resource, ultimately the ability to attempt access to a secured resource or function (such as a delete button) is controlled by the UI component's Rendered property.

By default, the Rendered property is set to true. By dynamically changing this value based on the permission, the UI component can be shown or hidden. For example, if the user has the appropriate permission, the Rendered property should be set to true so that the UI component is shown. If they do not have permission, the property should be set to false and the UI component hidden from view.

Note:

The ability to evaluate a policy is limited to the current request. For this reason, it is important to understand where the policy evaluation occurs, because evaluating the policy at anything other than the request scope can lead to unexpected results.

You can use Expression Language (EL) to evaluate the policy directly in the UI, while the use of Java enables you to evaluate the policy from within a managed bean. ADF Security implements several convenience methods for use in EL expressions to access ADF resources in the security context. For example, you can use the EL expression convenience methods to determine whether the user is allowed to access a particular task flow.

28.6.1 How to Evaluate Policies Using Expression Language (EL)

The use of EL within a UI element allows for properties to be defined dynamically, resulting in modification of the UI component at runtime. In the case of securing resources, the UI property of interest is the Rendered property, which allows you to show and hide components based on available permissions.

To evaluate a policy using EL, you must use the ADF Security methods in the security context (#{securityContext...}). These methods let you access information in the ADF security context for a particular user or ADF resource.

Table 28-8 shows the EL expression that is required to determine whether a user has the associated permission. If the user has the appropriate permission, the EL expression evaluates to true; otherwise, it returns false.

Table 28-8 EL Expression to Determine View Permissions on ADF Resources

Expression Expression action

#{securityContext.taskflowViewable[MyTaskFlow]}

For example:

#{securityContext.taskflowViewable[/WEB-INF/audit-expense-report.xml#audit-expense-report]}

Where MyTaskFlow is the WEB-INF node-qualified name of the task flow being accessed. Returns true if the user has access rights. Returns false if the user does not have sufficient access rights.

#{securityContext.regionViewable[MyPagePageDef]}

Where MyPagePageDef is the qualified name of the page definition file associated with the web page being accessed. Returns true if the user has access rights. Returns false if the user does not have sufficient access rights.


Note:

In the case of page permission, the value of the page definition can be specified dynamically by using late-binding EL within a managed bean, as described in Section 28.2.3, "What You May Need to Know About the valid-users Role".

Table 28-9 shows the EL expression that lets you get general information from the ADF security context not related to a particular ADF resource. For example, you can access the current user name when you want to display the user's name in the user interface. You can also check whether the current user is a member of certain roles or granted certain privileges. Your application may use this result to dynamically hide or show menus.

Table 28-9 EL Expression to Determine User Information in ADF Security Context

Expression Expression action

#{securityContext.userName}

Returns the user name of the authenticated user.

#{securityContext.userInRole['roleList']}

Where roleList is a comma-separated list of role names. Returns true if the user is in at least one of the roles. Returns false if the user is in none of the roles, or if the user is not currently authenticated.

#{securityContext.userInAllRoles['roleList']}

Where roleList is a comma-separated list of role names. Returns true if the user is in all of the roles. Returns false if the user is not in all of the roles, or if the user is not currently authenticated.

#{securityContext.userGrantedPermission['permission']}

Where permission is a string containing a semicolon-separated concatenation of permissionClass=<class>;target=<artifact_name>;action=<action>. Returns true if the user has access rights. Returns false if the user does not have sufficient access rights.

Note that the convenience methods taskflowViewable and regionViewable shown in Table 28-8 provide the same functionality.


To associate the rendering of a navigation component to a user's granted permissions on a target task flow or page definition:

  1. In the Application Navigator, double-click the page.

  2. Select the component that is used to navigate to the secured page.

  3. In the Property Inspector, select Expression Builder from the dropdown menu displayed to the right of the Rendered property, as shown in Figure 28-49.

    Figure 28-49 Binding the Rendered Property to Data

    Rendered Property usage
  4. Enter the appropriate EL expression for the ADF resource that the user will attempt to access.

    For example, to limit access to a task flow, you would enter an expression #{securityContext.taskflowViewable['target']} like the one shown in Figure 28-50. In this example, audit-expense-report is the secured target task flow.

    Figure 28-50 Defining EL in the Bind to Data Dialog

    Rendered property and EL usage
  5. Click OK.

When you run the application, the component will be rendered or hidden based on the user's ability to view the target page.

28.6.2 What You May Need to Know About Delayed Evaluation of EL

The ability to evaluate a security permission is scoped to the request. If you want to evaluate permissions to access a target page from a managed bean that is scoped to a higher level than Request (for example, a global menu that is backed by a session-scoped managed bean), you must implement delayed EL evaluation (late-binding). By passing in the target page as a managed property of the bean, you ensure that the EL expression is evaluated only after the required binding information is available to the session-scoped bean. Because EL is evaluated immediately when the page is executed, placing the EL expression directly in the properties of a UI component, backed by a session-scoped bean, would result in an out-of-scope error.

Example 28-7 shows a property (authorized) of a session-scoped bean that returns true or false based on a user's ability to view a named target page. In this case, the _targetPageDef variable is a managed property containing the name of the target page. Within the UI, the EL expression would reference the authorized property, rather than securityContext.regionViewable.

Example 28-7 Delayed EL Evaluation in a Session-Scoped Managed Bean

public boolean isAuthorized() 
{
 if (_targetPageDef != null) {
  FacesContext ctx = FacesContext.getCurrentInstance();
  ValueBinding   vb = ctx.getApplication().createValueBinding ( 
  "#{securityContext.regionViewable['" + _targetPageDef "']}" );
  if (vb != null) {
    Object authResult = vb.getValue(ctx);
    return (Boolean) authResult;
    }
  else  {
    ctx.addMessage(null, new FacesMessage (
    FacesMessage.SEVERITY_WARN, "Access Permission not defined! " , null));
    return(true);
    }
}

28.6.3 How to Evaluate Policies Using Java

To evaluate the security policies from within Java, you can use the hasPermission method of the Oracle ADF Security context. This method takes a permission object (defined by the resource and action combination) and returns true if the user has the corresponding permission.

In Example 28-8, a convenience function is defined to enable you to pass in the name of the page and the desired action, returning true or false based on the user's permissions. Because this convenience function is checking page permissions, the RegionPermission class is used to define the permission object that is passed to the hasPermission method.

Example 28-8 Using the hasPermission Method to Evaluate Access Policies

private boolean TestPermission (String PageName, String Action)  {
  Permission p = new RegionPermission("view.pageDefs." + PageName + "PageDef",                                           Action);
  if (p != null) {
     return ADFContext.getCurrent().getSecurityContext().hasPermission(p);   
 }
 else {
     return (true);
 }

As it is possible to determine the user's permission for a target page from within a backing bean, you can now use this convenience method to dynamically alter the result of a Faces navigation action. In Example 28-9, you can see that a single command button can point to different target pages depending on the user's permission. By checking the View permission from the most secured page (the manager page) to the least secured page (the public welcome page), the command button will apply the appropriate action to direct the user to the page that corresponds to their permission level. The backing bean that returns the appropriate action is using the convenience method defined in Example 28-8.

Example 28-9 Altering a Page Navigation Result Based on a Permission Check

//CommandButton Definition
<af:commandButton text="Goto Your Group Home page"
  binding="#{backing_content.commandButton1}"
  id="commandButton1"

  action="#{backing_content.getSecureNavigationAction}"/>

//Backing Bean Code
    public String getSecureNavigationAction() {
      String ActionName;
      if (TestPermission("ManagerPage", "view"))
        ActionName = "goToManagerPage";
      else if (TestPermission("EmployeePage", "view"))
        ActionName = "goToEmployeePage";
      else
        ActionName = "goToWelcomePage";
      return (ActionName);
    }

28.7 Getting Other Information from the Oracle ADF Security Context

The implementation of security in a Fusion web application is by definition an implementation of the security infrastructure of the Oracle ADF framework. As such, the security context of the framework allows access to information that will be required as you define the policies and the overall security for your application.

28.7.1 How to Determine Whether Security Is Enabled

Because the enforcement of Oracle ADF Security can be turned on and off at the container level independent of the application, you should determine whether Oracle ADF Security is enabled prior to making permission checks. This can be achieved by evaluating the isAuthorizationEnabled() method of the Oracle ADF Security context, as shown in Example 28-10.

Example 28-10 Using the isAuthorizationEnabled() Method of the Oracle ADF Security Context

if (ADFContext.getCurrent().getSecurityContext().isAuthorizationEnabled()){
  //Permission checks are performed here.
}

28.7.2 How to Determine Whether the User Is Authenticated

As the user principal in a Fusion web application is never null (that is, it is either anonymous for unauthenticated users or the actual user name for authenticated users), it is not possible to simply check whether the user Principal is null, to determine if the user has logged on or not. As such, you must use a method to take into account that a user Principal of anonymous indicates that the user has not authenticated. This can be achieved by evaluating the isAuthenticated() method of the Oracle ADF security context, as shown in Example 28-11.

Example 28-11 Using the isAuthenticated() Method of the Oracle ADF Security Context

// ============ User's Authenticated Status =============
private boolean _authenticated;
public boolean isAuthenticated() {
_authenticated = ADFContext.getCurrent().getSecurityContext().isAuthenticated();
    return _authenticated;
}

28.7.3 How to Determine the Current User Name

Fusion web applications support the concept of public pages that, while secured, are available to all users. Furthermore, components on the web pages, such as portlets, require knowledge of the current user identity. As such, the user name in a Fusion web application will never be null. If an unauthenticated user accesses the page, the user name anonymous will be passed to page components.

You can determine the current user's name by evaluating the getUserName() method of the Oracle ADF security context, as shown in Example 28-12. This method returns the string anonymous for all unauthenticated users and the actual authenticated user's name for authenticated users.

Example 28-12 Using the getUserName() Method of the Oracle ADF Security Context

// ============ Current User's Name/PrincipalName =============
     public String getCurrentUser() {
      _currentUser = ADFContext.getCurrent().getSecurityContext().getUserName(); 
         return _currentUser;
     }

Because the traditional method for determining a user name in a Faces-based application (FacesContext.getCurrentInstance().getExternalContext().getRemoteUser()) returns null for unauthenticated users, you need to use additional logic to handle the public user case if you use that method.

28.7.4 How to Determine Membership of a Java EE Security Role

Although Fusion web application security is centered around JAAS policies, you will likely still need to use Java EE security roles to secure components within an application page based on role membership. As Fusion web applications are JavaServer Faces-based applications, you can use the isUserInRole(roleName) method of the Faces external context, as shown in Example 28-13, to determine whether a user is in a specified role.

In this example, a convenience method (checkIsUserInRole) is defined. The use of this method within a managed bean enables you to expose membership of a named role as an attribute, which can then be used in EL.

Example 28-13 Using the isUserInRole(roleName)) Method of the Faces Context

public boolean checkIsUserInRole(String roleName){
        return 
(FacesContext.getCurrentInstance().getExternalContext().isUserInRole(roleName));
}

public boolean isTechnician() {
        return (checkIsUserInRole("technicians"));
 }

28.8 Testing ADF Security with Integrated WLS in JDeveloper

Oracle JDeveloper's Integrated WLS enables you to run the application directly. However, at this time, JDeveloper does not support application-level security in Integrated WLS. When you run the application using Integrated WLS, JDeveloper migrates the jazn-data.xml file to the domain-level system-jazn-data.xml policy store. In the migration process, JDeveloper maps the Oracle Platform Security (JPS) application role member classes to the WebLogic Server (WLS) member classes and migrates the users to WLS identity store users and roles to WLS identity store groups. In WebLogic Server, users is an implicit group equivalent to JPS authenticated-role.

Example 28-14 Application Role Fragment in system-jazn-data.xml File

<app-roles>
   <app-role>
      <name>fod-user</name>
      <guid>FFFF394F696E786F4134485764511002</guid>
      <display-name/>
      <description/>
      <class>oracle.security.jps.service.policystore.ApplicationRole</class>
      <members>
         <member>
            <name>fod-user</name>
            <class>weblogic.security.principal.WLSGroupImpl</class>
         </member>
      </members>
   </app-role>
</app-roles>

When you run the application, Integrated WLS executes the JpsFilter definition in the web.xml file to set up the JPS policy provider. The filter defines settings that indicate that your servlet has special privileges and the doasprivileged setting specifies the privileges that are allowed. Example 28-15 shows the filter definition that the Configure ADF Security wizard adds to the web.xml file. It is important that the JpsFilter is the first filter in the web.xml file.

Example 28-15 JpsFilter Definition for ADF Authorization

<filter>
  <filter-name>JpsFilter</filter-name>
  <filter-class>oracle.security.jps.ee.http.JpsFilter</filter-class>
  <init-param>
    <param-name>enable.anonymous</param-name>
    <param-value>true</param-value>
  </init-param>
  <init-param>
    <param-name>remove.anonymous.role</param-name>
    <param-value>false</param-value>
  </init-param>
  <init-param>
    <param-name>addAllRoles</param-name>
    <param-value>true</param-value>
  </init-param>
  <init-param>
    <param-name>jaas.mode</param-name>
    <param-value>doasprivileged</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>JpsFilter</filter-name>
  <url-pattern>*.jspx</url-pattern>
  <dispatcher>FORWARD</dispatcher>
  <dispatcher>REQUEST</dispatcher>
</filter-mapping>
<filter-mapping>
  <filter-name>JpsFilter</filter-name>
  <url-pattern>*.jsp</url-pattern>
  <dispatcher>FORWARD</dispatcher>
  <dispatcher>REQUEST</dispatcher>
</filter-mapping>

28.9 Preparing for Deployment to a Production Environment

Deploying a Fusion web application to a production application server involves migrating application-level policy data to a domain-level policy store. Your application stores the application-level policies in the jazn-data.xml file-based repository. Once migrated to the domain-level policy store, the policy data will be merged into the system-jazn-data.xml file.

You perform this task outside of JDeveloper, using the supplied migrateSecurityStore command. For details about using this command to migrate your application's policy data to the domain-level policy store, see "Migrating the Security Repository to a Production Environment" in the "Developing Secure Applications" section of the JDeveloper online help.