DOWNLOAD
 Oracle JDeveloper
   TAGS
adf, java, All
product logo Taking an Oracle ADF Application from Design to Reality

By Chris Muir ACE Director and Penny Cookson ACE

Chapter 5 - The "Won't-Have" Requirements (But We'll Implement Them Anyway): Preventing Malicious Access

Published May 2009

 Click here to see "Taking an Oracle ADF Application from Design to Reality" description and Table of Contents

In this chapter we will add some functionality to prevent malicious access by blocking any IP address that's undertaken three consecutive queries in the last hour that failed to find any results. We could do the check at the time the user hits the Enquiry button, and reject the query if the user has too many failures, but it is cleaner to hide the button immediately they have three failures, so they cannot attempt to continue. We already have the user's IP address from work done in Chapter 3.

In a similar manner to the previous phases we need to break these requirements down into discrete solvable units, including:

  1. Create a View Object to allow us to access the query results from the previous hour.
  2. Modify the page bindings to allow us to access the IP Check information.
  3. Identify an event from which to execute the IP address check.
  4. Modify the page components to disable the Enquiry button when the check has failed.

Create a View Object to allow us to access the query results from the previous hour.

We create a view object called IpCheckView. The view object will be Read-only access through a SQL query. It does not need to return a meaningful value since we just want to know how many rows are returned so we just select a literal 'x'. The view will have a single bind parameter, pUserIp, which we use to pass in the users' IP address.

Figure1

We will need to make the View object available from the Application Module.

Figure2

Modify the page bindings to allow us to access the IP Check information.

Since we are going to need to refer to the IP address from the page, we need to change our EnquiryBean class. We can add the following code:

  String userIPAddr;

  public String getuserIPAddr() {
     return userIPAddr;
  }

  public void setuserIPAddr(String userIPAddr) {
      this.userIPAddr = userIPAddr;
  }
And then change the storeUserInformation method as follows:
public void storeUserInformation() {
       
                              
setuserIPAddr(getRemoteAddr());
      String userTermsAndConditions = getTermsAndConditions();
      String userEnquirySource = getEnquirySourceCode();
      
      DCDataControl dc = BindingContext.getCurrent().getDefaultDataControl();
      ApplicationModule am = (ApplicationModule)dc.getDataProvider();
      AppModuleImpl service = (AppModuleImpl)am;
      
      service.logSession(userIPAddr, userTermsAndConditions, userEnquirySource);
    }
                            
Note that only line 2 has changed.

Now we need to modify the bindings of the SearchPage to include an iterator for the IpCheckView.

Figure3

In order to fetch the records from the new IpCheckView1Iterator iterator we will need to create an action binding for the ExecuteWithParams operation.

Figure4

In the Create Action dialog we select an iterator of IpCheckView1Iterator from the drop-down list and an Operation of ExecuteWithParams.

The easiest way to link the bind parameter pUserIp with the IP address we have determined for the user of the page, is to use the Expression Builder.

Figure5

Use the Expression Builder to set the value of the bind parameter to #{enquiryBean.userIPAddr}. We now have the records and query operation from the IpCheckView available to our page, and our bindings will appear as follows.

Figure6

Notice that ExecuteWith Params1 is bound to the IpCheckViewIterator. We will use this operation to fetch the number of records from the IpCheckView view object.

Figure7

Identify an event from which to execute the IP address check.

We need to check the number of failed queries for the current IP address after each enquiry, so we will call ExecuteWith Params1 from the action on the Enquiry button.

Figure8

We also want to check the number of failed enquiries when the user first accepts the terms and conditions, in case they have closed their previous session and started a new one, but are accessing the page from the same IP address. We can add a call to the call ExecuteWith Params1 operation in the Action of the Accept button as well.

Modify the page components to disable the Enquiry button when the check has failed.

We can now hide the Enquiry button if they have too many failed query attempts. We set the Rendered property of the Enquiry button as follows:

Figure9

The page now looks as follows in Design mode.

Figure10

We can now run the page and test the IP check.

Enter an invalid search; we see no result:

Figure11

Enter an invalid search.

Figure12

Repeat the invalid search twice more and the page is now disabled from further queries:

Figure13

Summary

In this chapter we have added code to prevent malicious access by blocking any IP address that's undertaken three consecutive queries in the last hour that failed to find any results. One of the important techniques described in this series of articles is the maintenance of the page bindings directly, rather than indirectly through the creation of components in the page. You will find that this approach not only assists in creating more advanced functionality, but enhances our understanding of the technology. (For more information on Data Bindings, see Section 11 of Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework 11g Release 1.)

This chapter concludes this article!


 Click here to see "Taking an Oracle ADF Application from Design to Reality" description and Table of Contents