Java Cloud Service: Security

Java Cloud Service (JCS) provides a platform to develop and deploy business applications in the cloud. In Fusion Applications Cloud deployments customers do not have the option to deploy custom applications developed with JDeveloper to ensure the integrity and supportability of the hosted application service. Instead the custom applications can be deployed to the JCS and integrated to the Fusion Application Cloud instance.

This series of articles will go through the features of JCS, provide end-to-end examples on how to develop and deploy applications on JCS and how to integrate them with the Fusion Applications instance.

In previous article we implemented a simple ADF web application; in this article we will implement security for it. There are some differences on how security is implemented in Fusion Applications:

  • Identity propagation is not supported e.g. when application in JCS is accessed from Fusion Applications a separate login is required
  • Role hierarchies are not supported. In FA we have a comprehensive role hierarchy controlling access to the application. In Cloud there is only one level of roles that can be used to control access
  • For Fusion Application we use ApplCore data security feature to control access to data, this feature is not supported in JCS

Pre-requisites

Access to Cloud instance

In order to deploy the application access to a JCS instance is needed, a free trial JCS instance can be obtained from Oracle Cloud site. To register you will need a credit card even if the credit card will not be charged. To register simply click "Try it" and choose the "Java" option. The confirmation email will contain the connection details. See this video for example of the registration.

Once the request is processed you will be assigned 2 service instances; Java and Database. Applications deployed to the JCS must use Oracle Database Cloud Service as their underlying database. So when JCS instance is created a database instance is associated with it using a JDBC data source.

The cloud services can be monitored and managed through the web UI. For details refer to Getting Started with Oracle Cloud.

JDeveloper

JDeveloper contains Cloud specific features related to e.g. connection and deployment. To use these features download the JDeveloper from JDeveloper download site by clicking the “Download JDeveloper 11.1.1.7.1 for ADF deployment on Oracle Cloud” link, this version of JDeveloper will have the JCS integration features that will be used in this article. For versions that do not include the Cloud integration features the Oracle Java Cloud Service SDK or the JCS Java Console can be used for deployment.

For details on installing and configuring the JDeveloper refer to the installation guide.

For details on SDK refer to Using the Command-Line Interface to Monitor Oracle Java Cloud Service and Using the Command-Line Interface to Manage Oracle Java Cloud Service.

Access to a local database

The database associated with the JCS instance cannot be connected to with JDBC. Since creating ADFbc business component requires a JDBC connection we will need access to a local database.

Modify application

To illustrate data security we will modify the application by adding a column to the table that stores the person who created the row. This information can then be used in queries to restrict the access to the data.

Modify data model

Navigate to the “JCS_DEMO” table in the local database using the Database Navigator. Since we need to delete the data as we will add a non-nullable column, right click the table name and choose “Table -> Drop”:

On the Drop screen accept defaults and click “Apply”

Next we will recreate the table; right click the “Tables” node and choose “New Table”:

In the table create 3 columns:

  • KEY (VARCHAR 30, primary key)
  • VALUE (VARCHAR 100, not null)
  • OWNER (VARCHAR 100, not null)

Also migrate the data model to the JCS like we did in previous article.

Modify ADFBc objects

Next we add the new column to the entity object. Navigate to the “JcsDemoEO -> Attributes -> Add from Table” and select the new “OWNER” column:

We want the name of the user to be populated on the new column, so navigate to the properties of the “Owner” attribute. Check the “History Column” and choose “createdby” from the related list. Now when a record is created the name of the user is automatically stored on the owner column.

Next we add the new EO attribute to the VO; open JcsDemoVO and navigate “Attributes -> + -> Add Attribute from Entity”:

On the “Attributes” window opened move the “Owner” column to “Selected”:

Lastly we add the new attribute to the UI; open JcsDemo.jspx and navigate to “Data Controls -> JcsDemoVO1 -> Owner”, drag and drop the “Owner” attribute to te JcsDemo.jspx after the “Value” field as “ADF Output Text w/ Label”:

Create Identities

First we will create users and roles in the Identity Console such that we can access the application with different set of access rights. First we create roles “userRole” and “adminRole” to distinguish between the types of access:

Next we create “user” and “admin” users and assign the roles created before respectively:


Configure security

Enable security for the application

Next we enable security with the "Application->Secure->Configure ADF Security" for the ViewController project, this will generate various security related files. On the wizard select:

  • ADF security: choose "ADF Authentication and Authorization"
  • Authentication Type: "HTTPS Client Authentication (Public Key Certificate)" this will rely on the JCS authentication mechanism
  • Automatic Policy Grants: "No Automatic Grants"
  • Authenticated Welcome: accept defaults

Update web.xml

To enforce authentication we need to add a security constraint. Navigate “web.xml -> Security -> Security Constraint”. Remove the “afdAuthentication” constraint and click the plus sign to create new constraint. Within the constraint create new “Web Resource Collection” by clicking the plus sign and enter name “DemoConstraint”. For the new Web Resource create new “URL Pattern” by clicking the plus sign and enter value “/*”:

The configuration should be as follows:

  <security-constraint>
    <web-resource-collection>
      <web-resource-name>DemoConstraint</web-resource-name>
      <url-pattern>/*</url-pattern>
    </web-resource-collection>
  </security-constraint>
  <login-config>
    <auth-method>CLIENT-CERT</auth-method>
  </login-config>
 
Do note that at this point our page no-one can access the page as no-one has been granted access to it.

Implement Security

When security is enabled no-one will be able to access our page by default, so first we will need to grant access to the page for the users we created in JCS.

Create Users and Roles

Open “JcsDemo.jspx”, right click and choose “Edit authorization”:

On the “jazn-data.xml” navigate to the “User” tab and add user that match the users we created in JCS.

Next we create the roles matching the roles we created in JCS. Navigate to the “Application Roles” tab and create roles matching the roles created in JCS. Also assign the new roles to the new users created in previous step:

Grant Access to the Page

To allow the users to access the page we grant the page to the roles. Navigate to the “Resource Grants” tab and grant “View” access to the new roles:

Control Access to a Field

Next we want to control the access to the “Owner” field such that only administrator can see it. Navigate to the “Resource Grants” tab and click the plus sign right of the “Resource Type”. This allows us to create a custom resource type. In this example we create “SecuredField” resource type which we can use to control access to fields on the application:


Next we create a resource for a specific field that we want to secure, in this example we want to control who can access the owner field:

Next we grant the resource to the admin role such that only the administrator can access the field:


Finally we restrict the access to the field by only rendering it when the user has access to the resource defined above. Navigate to the “JcsDemo.jspx”, choose the “Owner” field and set the rendered property to:

#{securityContext.userGrantedResource['resourceName=Owner;resourceType=SecureField;action=view']}

With these changes when the “admin” access the application they can see the owner field:

While the “user” does not see the field:

Implement Data Security

Note that the call to hasPermission used in the following example works in 13.2 (and prior versions) and 14.1.4.0 (and subsequent versions). For versions between there would be AccessControlException exception for the class "oracle.security.jps.ResourcePermission"

Next we want to implement data security such that users can only see records that they have created. We can achieve this with view criterion that is applied on the view object. First we create a bind variable that will be used to restrict the data queried in the view object. Open the JcsDemoVO, navigate “Query -> Bind Variables -> +” and enter “UserName” as the name of the variable:

Next we create the view criteria that will be used to construct the where clause for the query. Navigate “Query -> View Criteria -> +” and enter the following:

  • Criteria Name: SecurityCriteria
  • Attribute: Owner
  • Operator: Equals
  • Operand: Bind Variable
  • Parameter: UserName
  • Ignore Null Values: unchecked

Next we apply the criteria to the view object instance. Open “JcsDemoAM” and navigate “Data Model : JcsDemoVO1 -> Edit”, select the “SecurityCriteria” and enter the following as the value of the “UserName” parameter:

adf.context.securityContext.getUserName()

This will restrict the user to only see records created by the currently logged in user.

Next we want to allow the administrator to have more access than the regular user. With the current implementation each user is restricted to own records. To allow additional access for the administrator we can customize the processing of our security view criteria. First we create new resource type used for controlling access to data. Use the same steps as in section “Control Access to a Field” to create a new resource type with name “SecureData” and action “viewAll”:

Next we create new resource to control access to data. Use the same steps as in section “Control Access to a Field” to create a new resource with name “JCS_DEMO”:

And grant the new resource to “adminRole”. Next we need to modify the application such that users with access to the new resource can see all the data while other only see their own data. We can achieve this by creating a custom adapter for the view criteria on the view object. To customize the view object behavior we need to generate the view object implementation class. Open the “JcsDemoVO”, navigate “Java -> Edit” and check the “Generate View Object Class” check box:

Open the generated file “JcsDemoVOImpl.java” and create a custom adapter as follows. Copy paste the code to “JcsDemoVOImpl.java”, for details of the code refers to the comments in the code:

    /**
    * Custom view criteria adapter used to customize the behavior of the
    * security criteria based on permissions defined for the current user
    */
    public class SecurityCriteriaAdapter extends CriteriaAdapterImpl 
                                         implements CriteriaAdapter {

        /*
         * Name of the criteria to be customized. 
         * The value must match the name of our security view criteria
         */
        private String SECURITY_CRITERIA = "SecurityCriteria";

        @Override
        protected String getCriteriaClause(AttributeDef[] attrDefs,
                                           ViewCriteria criteria) {
            String whereClause = null;
            /*
             * Only customize behavior of the security criteria, 
             * other processing continues as is
             */
            if (criteria.getName().equals(SECURITY_CRITERIA))       {
                
                /*
                 * Check whether the user is allowed to "viewAll" 
                 * on the "JCS_DEMO" table
                 */
                Permission permission = 
                   new ResourcePermission("SecureData", "JCS_DEMO", "viewAll");
                boolean viewAll =                
                    ADFContext.getCurrent().getSecurityContext()
                                           .hasPermission(permission);
                if (viewAll) {
                    /*
                     * User is allowed to see everything so we override the 
                     * where clause created by the security view criteria. 
                     * Since the criteria is using bind variable exception
                     * will be thrown if the bind variable reference does not 
                     * exist.  The bind variable will be compared to itself so 
                     * this will always evaluate to true.
                     */
                    whereClause = ":UserName = :UserName";
                } else {
                    whereClause = super.getCriteriaClause(attrDefs, criteria);
                }
            } else {
                whereClause = super.getCriteriaClause(attrDefs, criteria);
            }
            return whereClause;
        }
    }
 

Lastly we need to override the “getCriteriaAdapter” on the view object to include our custom adapter to the view criteria processing:

    // Adapter to customize the behavior of the criteria
    private SecurityCriteriaAdapter 
        SECURITY_CRITERIA_ADAPTER = new SecurityCriteriaAdapter();

    @Override
    public CriteriaAdapter getCriteriaAdapter() {
        return SECURITY_CRITERIA_ADAPTER;
    }
 
With these changes the where clause produced by the view criteria will be overridden if the user has "viewAll" access on the "JCS_DEMO" table, so in this example “admin” can see all data while “user” can only see her own data.

Summary

In this article we learned how to secure a ADF web application for Java Cloud Service. In future articles various other technologies and features such as integration to Fusion Applications etc. will be covered.


Comments:

Good post, however, is there a sample/ demo for Form based authentication?

I have implemented the form based authentication on JCS with unexplainable issues :
javax.faces.FacesException: #{loginBean.doLogin}: java.security.AccessControlException: Type "weblogic.security.URLCallbackHandler" not allowed.

if you would please, provide a walk through for form based login/ custom login.

thanks

Posted by ola on July 13, 2014 at 03:06 PM PDT #

JCS does support FORM based authentication, refer to documentation:
http://docs.oracle.com/cloud/latest/javacs_common/CSJSU/java-develop006.htm
http://docs.oracle.com/cloud/CSJSU/dev_app.htm#BCEEFHFB

Unfortunately I won't be able to create a blog post example right now as I am heading off to vacation. However I did do a simple test and confirmed that simple FORM based authentication does work. The only difference to the steps described in this blog post were on the "Enable security for the application" where instead of "Authentication Type: HTTPS Client Authentication (Public Key Certificate)" I chose "Form-Based authentication" and opted to generate the login / error pages by choosing the "Generate Default Pages". With these the configuration in web.xml is
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/login.html</form-login-page>
<form-error-page>/error.html</form-error-page>
</form-login-config>
</login-config>

and when accessing the application I get prompted for FORM based login. So the FORM based login does work and the login / error pages can be configured. The exception that you see is related to restrictions on the APIs that can be used, see:
http://docs.oracle.com/cloud/latest/javacs_common/CSJSU/java-appendix001.htm

where "Unsupported WebLogic Server Capability" list contains:
weblogic.security.*
All security is handled at the Oracle Cloud identity management level. No custom security provider or model is supported. However authenticated user's principles can be read.

Posted by Jani Rautiainen on July 14, 2014 at 01:10 AM PDT #

Post a Comment:
  • HTML Syntax: NOT allowed
About

Follow us on twitter Fusion Applications Extensibility, Customizations and Integration forum Fusion Applications Dev Relations YouTube Channel
This blog offers news, tips and information for developers building extensions, customizations and integrations for Oracle Fusion Applications.

Search

Categories
Archives
« July 2015
SunMonTueWedThuFriSat
   
2
3
4
5
8
10
11
12
15
18
19
22
23
24
25
26
27
29
30
31
 
       
Today