Customizing Content With Oracle XML DB and J2EE features

Security Implementation

December 2002
  Oracle9i  

The XMLNews application has adopted Form-based-authorization to customize the user authentication  interface.  In form-based authentication, you can customize the login screen and error pages that are presented to the end user by an HTTP browser. Also, the content of the user dialog box is sent as plain text, and the target server is not authenticated.

In XMLNews application, authentication is only for the UI (JSPs) i.e Views layer and not for the underlying EJBs. From the security perspective, there are two types of web pages in the application; authenticated and non-authenticated pages. To access the authenticated pages, end-users have to be authenticated. In the current sample application, user validation for username/password is done against Oracle database table using custom UserManager class. Apart from the username/password validation, role validation is also done. With this, the application is implemented in such a way that content of the authenticated page will also depend on the role of the user. Following are the implementation details:

Custom User Interface
Custom login page is defined in web.xml file which is read by OC4J at the application start up. Here is how web.xml entries look for the XMLNews application. This configuration defines the custom loginMain.jsp that is used in the application for login interface. Also, errorLogin.jsp when the login fails.
............
<login-config>
<auth-method>FORM</auth-method>
<realm-name>Form-Based Authentication for XML NEWS</realm-name>
<form-login-config>
<form-login-page>user/loginMain.jsp</form-login-page>
<form-error-page>user/errorLogin.jsp</form-error-page>
</form-login-config>
</login-config>
.................


Defining URLs to be authenticated
All the pages to be authenticated will have a defined URL pattern. In the XMLNews sample, all the pages having pattern starting with 'auth' will need to be authenticated before viewing the page. The URL pattern is defined in web.xml. Note the role definitions also.
............
<security-constraint>
<web-resource-collection>
<web-resource-name>xmlnews</web-resource-name>
<url-pattern>/xmlnews/auth*</url-pattern>
</web-resource-collection>

<auth-constraint>
<role-name>admins</role-name>
<role-name>users</role-name>
<role-name>manager</role-name>
<role-name>newsprovider</role-name>
<role-name>enduser</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>NONE</transport-guarantee>
</user-data-constraint>

</security-constraint>

.................


Using custom UserManager Class
OC4J has support for pluggable UserManagers. The class: MyUserManager.java   under oracle.otnsample.eis layer implements the com.evermind.security.UserManager interface. The UserManager is responsible for locating, creating, editing, removing and managing Group object. User management is done in the database.  The custom UserManager class will validate the username/password and associated role of the user to allow access to the authenticated pages. OC4J will make use of the custom UserManager class when orion-application.xml has valid entries defining user manager class.
<?xml version="1.0"?>
<!DOCTYPE orion-application PUBLIC "-//Evermind//DTD J2EE Application runtime 1.2//EN"
"http://xmlns.oracle.com/ias/dtds/orion-application.dtd">

<orion-application deployment-version="9.0.2.0.0" default-data-source="jdbc/OracleDS">
<data-sources path="./data-sources.xml" />
<principals path="./principals.xml" />
<user-manager class="oracle.otnsamples.eis.MyUserManager"> </user-manager>

.................

MyUserManager.java extends from SimpleUserManager.java and has implemented following 3 methods:

protected boolean userExists( String username );
protected boolean checkPassword( String username, String password );
protected boolean inGroup( String username, String groupname );


The password checking and inGroup validation is done using XMLNEWS schema table 'USERS' in Oracle Database.
Here is the code snippet for 'checkPassword' method in MyUserManager.java


 .........
protected boolean checkPassword(String username, String password) {

// Rowset to get results of the query to find password of the user.
RowSet rSet;
String pword = null;

// create arraylist to store parameters to be sent to the query.
ArrayList params = new ArrayList();
params.add(username);

// set the default flag status to false.
boolean flag = false;
try {

// Get an instance of DBBroker class and Execute the SQL Statement

// The sql queries the password for the given username
rSet = DBBroker.getDBBroker("xmlnewsDB").execute("SELECT password FROM users
WHERE user_name =? ", params);

// get password from rowset
while(rSet.next()) {
pword = rSet.getString(1);
}

// if password is correct then, flag true.
if(password.equals(pword)) {
flag = true;
}

} catch(Exception Ex) {

}
return flag; // return flag
}
............


All the application users will fall under different groups. This is defined in principals.xml file which is read by OC4J at the application startup. Here is the listing of principals.xml file which has defined five groups for the application which will find corresponding mapping to the role in the USERS table in the database.

<?xml version="1.0" standalone='yes'?>
<!DOCTYPE principals PUBLIC "//Evermind - Orion Principals//"
"http://xmlns.oracle.com/ias/dtds/principals.dtd">

<principals>
<groups>
<group name="users" />
<group name="admins" />
<group name="manager" />
<group name="newsprovider" />
<group name="enduser" />
</groups>

<users></users>
</principals>


Below is the code snippet for 'inGroup' method in MyUserManager.java which checks the role of the user from database, matches the role and group defined in principals.xml file. So, the role obtained and validated thus is made use of while displaying the content of the views i.e JSPs in the application.
 ..................
protected boolean inGroup(String username, String groupname) {

// rowset to hold resultsof the query
RowSet rSet;
String uRole = null;

// array list to pass values for the bind parameters to the query.
ArrayList params = new ArrayList();
params.add(username); // add username
try {

// Get an instance of DBBroker class and Execute the SQL Statement
// The sql queries the role for the given user.
rSet = DBBroker.getDBBroker("xmlnewsDB").execute("SELECT lower(role)
FROM users WHERE user_name =? ", params);

// get the role of the user from rowset.
if(rSet.next()) {
uRole = rSet.getString(1);
}
} catch(Exception Ex) {

}

// return true when the role maps correctly to the groupname identified
// in the application defined in principals.xml
return uRole.equals(groupname);
}
...........



Post you comments in the OTN Sample Code forum
E-mail this page
Printer View Printer View
Oracle Is The Information Company About Oracle | Oracle RSS Feeds | Careers | Contact Us | Site Maps | Legal Notices | Terms of Use | Privacy