Generation of dynamic Web content has been a significant area of interest for the technical and business community since the inception of application server technology.IBM ® WebSphere® Application Server V5 architecture provides run time storage containers for successful deployment and access of Web components, and generation of dynamic responses based on client requests through container-embedded Web servers and other standalone Web servers.
This article focuses primarily on developing JavaTM servlet applications and how application-level security can be implemented to secure those servlet applications through exploitation of HttpSession capabilities of WebSphere Application Server. A case study is illustrated, where a security model similar to the J2EE declarative model is defined and stored in the HttpSession, thereby providing a simple mechanism to secure servlet Web applications at a level of granularity applicable to the servlet application database tables and table attributes.
The model illustrated in this article will outperform the J2EE programmatic security model by facilitating secure access to servlet resources at a level lower than verifying specific user login and associated roles. The model described in this article eliminates the need for the users of servlet Web applications to administer and configure security roles, often required for the deployment and access of server-side application components.
Included with this article as a case study are samples of client and server-side test automation applications, developed during my prior experience with the WebSphere test automation team. The significance of these samples is not so much the function of these applications, but that they provide Java code examples showing the implementations of both client and server-side Web applications, illustrating the design of secure Web applications and WebSphere Application Server handling of client requests through Hypertext transport protocol (HTTP).
After reading this article, Web developers and testers should be able to understand the overall operating environment of server-side Java servlet applications enough to devise and implement application-level software security layers similar to the one presented in this article for securing servlet Web applications.
Java servlets and run time architecture
This section provides background information on how data flows during a typical run time servlet invocation by a Web client and standalone Web servers (or other embedded Web servers from within WebSphere Application Server.
The Java servlet Application Programming Interface (API) provides a component-based and architecture-neutral means to develop and deploy Web-based applications for generation of dynamic Web content and enhanced user interaction. Dynamic Web content generated as a response by servlet applications for a specific client request is a Web page composed of HTML elements. The response received by a Web client depends upon the nature of the request made by the Web client. Figure 1 illustrates the data flow of a servlet's run time invocation. A Web client's request for access to a servlet resource residing within the WebSphere Application Server's Web container is sent as an HTTP request to a Web server. Programmatically, a Web client's request data can be envisioned as being encapsulated within an HTTP request header object to be examined by the Web server. The Web server analyzes the incoming HTTP request object and passes the HTTP request immediately to a WebSphere plug-in, which then establishes a connection with the Web container of the WebSphere Application Server. The servlet invoked as a result of a Web client's HTTP request can communicate with external application data stores to provide an HTTP response to the Web client. Once the necessary run time servlet code execution is completed to retrieve and build the required HTML pages, the Web server provides an HTTP response to the Web client, returning the output generated by WebSphere Application Server's Web container along with any static response header information.
Figure 1. Data Flow Diagram (DFD) for servlets run time invocation
Given the ability of servlet applications to respond to a Web client's request with the required application data, securing the application data is of critical concern for Web application developers, small business entities and other large businesses interested in developing enterprise e-business applications with transactional capabilities. We will focus on implementing application-level software security for HTML form-based servlet applications, as opposed to complex transactional enterprise applications.
As a primer to understanding the principle behind the design and implementation of application-level software security, this article provides some background information on WebSphere Application Server's Session management capabilities. An HttpSession established between a Web client and the WebSphere Application Server uniquely identifies the particular user login or the client that requested an HttpSession with the WebSphere Application Server. A cookie is sent as an acknowledgment to the client while establishing an HttpSession. Java plug-in software provides cookie support through browser APIs to accept and send cookie-related information to the WebSphere Application Server. It is important to note that different Web browser clients have varied implementations of the browser APIs on different platforms and, hence, specific versions of plug-in software, browsers and platforms most likely dictate how cookie information is interpreted and processed during a Web client's request and response activities. Figure 2 shows the ESD depicting the sequence of events that can occur during a Web client's request to establish secure access to an application data store and manipulate data through invocation of the application's servlet components. The subsequent topics in this article focus on a case study of a WebSphere test automation application and its underlying security.
Figure 2. Event Sequence Diagram (ESD) of a session management application
Overview of the case study application
The application we will use for case study is a WebSphere Application Server test automation application. The objective of the application is to automate the process of testing the WebSphere Application Server functionality, as opposed to performing manual testing. During the manual testing process, a tester has to download the required WebSphere Application Server builds, install the builds in the required platforms and complete execution of a suite of test cases. Automation can enhance product quality, minimize human errors, provide cost savings and reduce software product maintenance cycle time.
The automation application that was implemented had the capability of delivering the WebSphere Application Server builds to the test machines and executing test scripts to perform automated testing. Information about daily builds that were delivered, available test plans, test systems, and test results were stored in an IBM DB2® V7 database for end users to access and manipulate data from the test automation server. An example of manipulating test automation server data by a Web client is updating an existing test machine component in the testing infrastructure through invocation of a Test System Maintenance (TSM) servlet, or updating available test plan information through the invocation of a test plan maintenance servlet. Certain servlet pages display HTML data, preventing users from manipulating the test data. An example of this scenario is displaying the available daily build information such as build number, build release, test platform for the build, and build date.
The Sequence of events that can occur in the test automation application closely resembles the ESD in Figure 2. Human and computer interaction for the test automation application is facilitated through a Web interface composed of client and server application invocation links. Users of the application must always log on to the test automation application and create a valid HTTP session uniquely identifying the user before accessing the test automation infrastructure and test automation data. When the user fails to invoke the client login before access to the test automation servlets, error messages are displayed based upon the absence of a valid HTTP session. If a valid HTTP session is detected by the servlet code, the user is redirected to the required page composed of static and/or dynamic HTML elements with access to the test automation data. Data access and manipulation by the user are dependent upon the access permissions defined for the specific user by the administrator of the application, and the information contained in the user-specific session.
The Java applet:
- was created using Java swing user interface components.
- displays a graphical user interface (GUI) consisting of username and password validation fields, and labels and buttons with suitable images.
- displays a custom frame to display error messages and to provide suitable user feedback.
- executes a userLogin servlet to validate the user and create user-specific sessions and access permissions to the test automation database.
- sends communication messages to WebSphere Application Server through the communication network to execute the userLogin servlet.
- signals the applet with the results of user authentication by writing a Boolean string to the servlet's output stream, then reads the servlet's output stream and provides feedback to the user.
Listing 1. Java applet code snippets for validating user log in and updating user password
/* Executes the user login servlet to validate user login */
public String validateLogin(String isvalid, String username, String password){
try {
URL url = new URL("http://"+servername+"/servlet/userLogin?name="
+username+"&passwd1="+password+"");
URLConnection con = url.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader
(con.getInputStream()));
isvalid = in.readLine();
return(isvalid);
} catch(MalformedURLException M) {
return("MalformedURLException Occured");
} catch(IOException E) {
return("IOException Occured");
} catch(Throwable t) {
return(t.toString());
}
}
/* Executes the password update servlet to update password */
public String updatePasswd(String isvalid, String name, String
passwd1, String passwd2) {
try {
URL url = new URL("http://"+servername+"/servlet/passwordUpdate?
name="+name+"&passwordUpdate1="+passwd1+
"&passwordUpdate2="+passwd2+"");
URLConnection con = url.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader
(con.getInputStream()));
isvalid = in.readLine();
return(isvalid);
} catch(MalformedURLException M) {
return("MalformedURLException Occured");
} catch (IOException E) {
return("IOException Occured");
}
}
/* Encrypts user and password information */
public String encryptPasswd(String username, String password) {
String usrhash = String.valueOf(username.hashCode());
String passhash = String.valueOf(password.hashCode());
String encrypt = usrhash.concat(passhash);
return(encrypt);
}
|
Figure 3 shows the GUI for the client-side Java applet. The applet code listens for the button click event in order to display the login and the update password windows, which consist of images, labels, button and text fields. User login and update password interfaces open a URL connection with the location of the servlet resources userLogin and passwordUpdate correspondingly, and read the stream written by the servlets to complete the user validation and password change requests from the client application.
Listing 1 shows the code snippets that perform user validation and password update functionalities. Java applet variables, such as servername that contribute to the building of a complete URL in Listing 1, are passed as a parameter to the applet using appropriate applet parameter tags. The username and password information entered by the Web client user needs to be encrypted using an encryption methodology before invoking the servlet resources to avoid unauthorized access to the application. The encryption technique shown in Listing 1 is the creation of an encrypted string resulting from the concatenation of the results returned by calling the hashCode()method on the username and password strings. The resulting encrypted string is compared to the corresponding value in the user database to validate the user login and to update the user password.
Figure 3. Applet login and password update windows
Test automation servlets were designed based on the required component functionalities, such as test system maintenance, test plans, builds, and test results. Test automation infrastructure consists of the following servlet components:
- Builds and Results Servlet - Displays details of WebSphere Application Server builds and test automation build results.
- Components Servlet - Allows the user to create, update and delete test system components, such as Web servers, Web browsers and application servers from within the automation framework.
- TSM and Property File Generation Servlet Component - Allows the user to maintain a test system in the automation framework, and generate a property file describing the properties of the test system such as available components and hardware and software information. Test systems information is initially added to the TSM database tables by a distributed automation client that runs in each test system. The automation client is notified of any changes to the test system components or configuration by means of the property file generated by the servlet component.
- Test Plans and Scripts List Servlet:
- Allows the user to create a test plan with a unique ID and associate a list of test scripts with the created test plan.
- Displays details of available test plans for test automation such as plan name, plan ID, associated scripts list, and test platforms, and allows the user to perform update and delete operations with a unique plan ID.
- Details Servlet - Displays details of a failed test plan in a tabular form, listing log files or directories.
- Framework Security Components:
- User Login Servlet - Given a username and password, this servlet performs user validation, defines user privileges, and saves the privilege information in a user-specific session.
- User Groups Servlet - Creates and maintains user groups (e.g. Read group- Read only).
- User Administration Servlet - Allows an administrator to add new users, update user information and access permissions.
- Data Security Layers - i.e. Database classes for IBM DB2 SQL query execution for automation server data maintenance. Automation server data maintenance was accomplished by the implementation of a command line processing Java program that reads keywords from the command line and performs IBM DB2 database export/import operations using text files. An example of data maintenance is performing database schema changes to the required database tables.
3. Sample servlet illustration
For the purposes of illustrating application security, we will look at the TSM servlet. Application security of the test automation servlet application is dictated by the data access rules for the associated database tables. The TSM servlet manipulates data from six different IBM DB2 database tables: computer, components, browser, httpserver, database and jdk. During the initialization phase of the TSM servlet (i.e. when the compiled servlet Java classes are loaded into the WebSphere Application Server Web container environment and initialized) the servlet's init(ServletConfig config)method is executed along with the applicable doGet or doPost method. Listing 2a shows the implementation of the TSM servlet's initialization.
Listing 2a. Initialization of TSM servlet
/* Initialization of TSM servlets */
public void init(ServletConfig config) throws ServletException {
super.init(config);
wn = new waspNames();
FunDBService FunDBS = new FunDBService(iErrMsg, wn.loadDBDriver,
wn.loadDBPwd);
FunDBS.loadComponents();
cons = FunDBS.GetConnected(pgmID);
/* Create and return an array of database connections. */
}
|
During the servlet's initialization, the servlet establishes connection with the DB2 databases by instantiating the COM.ibm.db2.jdbc.app.DB2Driver class and fetching a database connection for each database of interest. Application initialization errors are stored in the Java static StringBuffer iErrMsg. The test automation application maintains the WebSphere Application Server builds on a release basis and creates an array of database connections for the build releases. Since TSM maintenance functionality is not related to the build releases, a database connection is established with the Platform database in addition to other database connections. The six tables of interest to the TSM servlet belong to the Platform database. (The appendix in this article lists the table schemas associated with the TSM application.) FunDBService is a helper class that provides connectivity to the required database and maintains values for certain application state variables required for navigation through the test automation application. Examples of such state variables include a variable that tracks a servlet page loading HTML tags related to builds and release information, as opposed to a test automation servlet functionality that is not release-dependent.
Once initialization of the servlet is complete, the doGet (HttpServletRequest req, HttpServletResponse res) method of the TSM servlet executes. Listing 2b shows the implementation of the doGet request processing method for initial invocation of the TSM servlet. Figure 4a shows the result of executing the implementation in Listing 2b. If the user does not log in and create a valid HTTP session, the servlet redirects the user to login to the application and create a new session; otherwise, it displays a page containing links to accessible test systems based on user access permissions in the left frame. Again, initial creation of test systems in the TSM database tables is done by a distributed automation client as opposed to manual test systems creation.
Any updates to existing test systems can be accomplished by clicking the desired test machine in the left frame and updating the required form fields in the right frame. A test machine can be deleted in a similar fashion. Figure 4b shows the details of a test system in the TSM application, along with the form buttons and list of components that can be added to an existing test system. Individual components can be added to the test system by selecting the required component and clicking the Add button. Individual components can be deleted by using the check box and performing an update operation by clicking the Update button of the servlet.
Listing 2b. doGet request processing method for initial invocation of TSM servlet
public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
res.setContentType("text/html");
PrintWriter out = res.getWriter();
HttpSession hSess = req.getSession(wn.noNewSession);
StringBuffer errMsg = new StringBuffer();
FunDBService FunDBS = new FunDBService(errMsg, wn.noLoadDBDriver,
wn.noLoadDBPwd);
if(hSess==null) {
HttpSession hSess1 = req.getSession(wn.createNewSession);
hSess1.setAttribute(wn._pgmID, pgmID);
hSess1.setAttribute(wn._pgmVersion, pgmVersion);
hSess1.setAttribute(wn._pgmTitle, pgmTitle);
FunDBS.reDirect(out, req.getServerName());
return;
}
hSess.setAttribute(wn._pgmID, pgmID);
hSess.setAttribute(wn._pgmVersion, pgmVersion);
hSess.setAttribute(wn._pgmTitle, pgmTitle);
hSess.setAttribute(wn._serverName, req.getServerName());
hSess.setAttribute("_showRelease", "no");
if((hSess.getAttribute(wn._userID) == null)) {
FunDBS.reDirect(out, req.getServerName());
return;
}
/* if we had an error during Initialization */
if(iErrMsg.length() > 0 ) {
errMsg.append(iErrMsg);
FunDBS.displayError(hSess, out, wn.err01, wn.noClearMsg);
return;
}
Statement stmt = null;
ResultSet rs = null;
int dbIndex = 0;
String whichPage = req.getParameter("page");
/* output the top form */
if(whichPage == null) {
hSess.setAttribute(wn._title, "Test Systems");
hSess.setAttribute(wn._topFrameName, "Banner");
hSess.setAttribute(wn._topFrameServlet, "testSystems");
hSess.setAttribute(wn._leftFrameName, "Platforms");
hSess.setAttribute(wn._leftFrameServlet,"testSystems");
hSess.setAttribute(wn._riteFrameName, "PlatDetails");
hSess.setAttribute(wn._riteFrameServlet,"testSystems2");
hSess.setAttribute(wn._driverversion, "\"\"");
FunDBS.outerFrame(out, hSess);
}else if ( whichPage.compareTo("1") == 0 ) {
/* this would be the banner frame */
FunDBS.loadTopFrame(out, hSess);
}else { // Default is to generate the list of machines
for(int i=0; i < pmPage2.length; i++ ) {
if(pmPage2[i].startsWith("!Standard ")) {
out.println("<INPUT TYPE=hidden NAME=\"DBSelect\" VALUE=\""+
hSess.getAttribute(wn._dbIndex) +"\">");
} else if (pmPage2[i].startsWith("!Details ")) {
if((stmt = FunDBS.stmt(2, hSess, out, cons[dbIndex])) == null)
return;
RowComputer rowComputer = new RowComputer(errMsg, debug);
Vector computers = rowComputer.query(hSess, wn.err03, stmt, "");
if(errMsg.length() > 0)
FunDBS.displayError(hSess, out, wn.err04, wn.clearMsg);
for(int j=0; j < computers.size(); j++) {
RowComputer rC = (RowComputer) computers.elementAt(j);
/* default blue */
String kolor = wn.magenta;
/* taken out of service manually */
if(rC.inService == 0)
kolor = wn.gray;
/* machine is not responding */
else if (rC.inService == 2)
kolor = wn.red;
/* inservice and available */
else if ((rC.inService == 1) && (rC.available == 1))
kolor = wn.blue;
/* inservice and inUse */
else if ((rC.inService == 1) && (rC.available == 0))
kolor = wn.green;
/* property file not sent */
else if (rC.inService == 4)
kolor = wn.crimson;
/* property file not sent */
else if (rC.inService == 5)
kolor = wn.orange;
String displayName = "";
String nick = rC.nickName;
if(nick!=null) {
nick = nick.trim();
if(nick.equalsIgnoreCase("null"))
nick = null;
}
if((nick!=null)&&(nick.length() > 0))
displayName = nick;
else if((rC.machine != null) && (rC.machine.length() > 0 ))
displayName = rC.machine;
else if((rC.ipaddr != null) && (rC.ipaddr.length() > 0 ))
displayName = rC.ipaddr;
else if ((rC.machineID != null) && (rC.machineID.length() > 0 ))
displayName = rC.machineID;
out.println("<H3> <A HREF=\"/servlet/testSystems2?" +
"platdept="+java.net.URLEncoder.encode(rC.dept)+
"&machineid="+java.net.URLEncoder.encode(rC.machineID)+
"&ipaddr="+java.net.URLEncoder.encode(rC.ipaddr)+
"&computername="+java.net.URLEncoder.encode(rC.machine)+
"\" target=\"PlatDetails\"><Font Color="+ kolor +">"+ displayName +"
</A></font></H3>");
}
} else
FunDBS.RepVar(out, pmPage2[i], hSess);
}
}
if(errMsg.length() > 0) {
FunDBS.displayError(hSess, out, wn.err99, errMsg.toString());
return;
}
FunDBS.closeStmt(wn.err05, hSess, out, stmt);
out.close();
}
|
During the test system update request, the property file representing the TSM form fields is delivered to the automation client associated with the test system for subsequent updates by the client to the test system information in the automation server database tables. Listing 3 shows the implementation of the termination of TSM servlet services. During a request for the termination of Web container services, the TSM servlet's destroy() method is called to close all open database connections.
Listing 3. Termination of TSM services
/* Termination of TSM services */
public void destroy() {
if(cons == null) {
return;
} else {
FunDBService FunDBS = new FunDBService(iErrMsg,
wn.noLoadDBDriver, wn.noLoadDBPwd);
for(int i=0; i < cons.length; i++) {
cons[i] = FunDBS.closeCon(1, null, null, cons[i]);
}
}
}
|
Figure 4a. Run time invocation of Listing 2b
Figure 4b. Run time invocation of Listing 2b
The following sections highlight the security aspects of the TSM application during a user's request for data read and write in the TSM application.
This section describes application-level security features and how this principle was extended to secure the TSM application.
The administrator of the test automation application can define user groups for a given user. The administrator is distinguished from other users of the test automation application by storing the administrator's userID and password information in an encrypted file in the automation server and that of other users' userID and password information in a user database. Figure 5 shows the run time invocation of the dblogin servlet, which creates the encrypted identification file required for administrator login to the test automation database.
Users can belong to any one of the groups listed in Table 1 or be a member of more than one group. User group permissions are applied at the table level of the test automation application. In the case where a user belonged to more than one group, the group that gives the user most access permissions is applied. Further functionality, such as TSM, is dependent on the department that owns the test machine. In such cases, the users of the TSM application are initially assigned group permissions to all available departments specified by the components servlet. Permission can be revoked or downgraded from the permission hierarchy for specific departments through the user administration servlet. During the invocation of code shown in Listing 2b, the user is able to view only those department test systems for which the user has at least Read Only access. Further, a subset of access permissions apply to a given permission level. If a user belongs to a Delete group and inherits Delete permission for TSM functionality, Read, Update and Create permissions also apply.
Figure 5. Encrypted file creation servlet
Table1. User group permissions
| Permissions | 0 | 1 | 2 | 3 | 4 |
| Permission Name | None | Read only | Update | Create | Delete |
Even though group read and write access permissions to the test automation application are applied to the application database tables, as in the case of the TSM servlet that is dependent on other tables, permissions are applied to the primary computer table of TSM, and all other secondary component tables, such as browser, httpserver, database, and jdk, inherit the permissions of the computer table. This principle is programmatically applied at run time by saving the user and access permission information as a <key, value> pair inside the HtppSession that is created at the time of user login to the application. The HttpSession object is then analyzed by TSM to perform secure data manipulation by the end users. This code is typically executed by the client application at the time of user login to create user-specific sessions and to initialize the user session with personalized information, such as the userid and permitted access level for the specific login. The test automation application implements the login validation and access permissions creations code in the userLogin servlet. Table 2 shows the formats for access permissions information used for storing the user access permissions in the HttpSession object in the test automation application.
Table 2. Access permission formats in the HttpSession Object
| For functionality not associated with departments e.g. builds and results | |
| Key | Value |
| "(tablename)(permission name)" | "true" or "false" |
| For functionality associated with departments e.g. TSM | |
| Key | Value |
| "(tablename)(read)" | "dept. list" |
| "(tablename)(non read permissions) (dept.)" | "true" or "false" |
In case an administrator login is detected by the userLogin servlet, by comparing the client's login to that information contained in the encrypted file for the application administrator on the automation server, the value for any given permission key in the HttpSession object is set to "true"and the dept. list for a read permission will be comprised of all departments defined in the component table.
To have a better understanding of the behavior of TSM security, let us consider the class that performs database manipulation. In the test automation servlets, access to the database application is implemented through a separate software layer, a Java class that maintains information about the database schema for the corresponding servlet application, and performs secure and structured database queries into the database, such as Select, Create, Insert, Update and Delete. The test automation servlets, including TSM, use the corresponding software layer during client request processing to perform secure data manipulation. Since the software layer needs to know the access permissions of the client residing inside the HttpSession object, the servlets pass the HttpSession object as one of the parameters to the database method that handles the client's request processing. A Java null HttpSession object is often passed to the software security layers to indicate an administrator's or superuser's login to the test automation application. In certain cases, the string "superuser" is stored as a value to the key "department" to indicate a superuser's login.
Listing 4 shows the implementation details of the Select operation performed in the TSM software security layer RowComputer.java Method query takes the HttpSession hSess object as a parameter, along with others. If the analysis of hSessobject indicates a superuser login to the test automation application, then all rows are selected from the computer table; otherwise the implementation in Listing 5 executes, where the string format for data read as in Table 2 is constructed, and the value corresponding to the constructed key is retrieved from the hSessobject to obtain a list of departments for which the user has access in the TSM servlet. The list of retrieved departments in Java String format is then used to complete the query into the computer table.
Listing 6 shows the implementation details of the Delete operation performed in the TSM software security layer RowComputer.java. Method delete takes as the HttpSession hSess object as a parameter, along with others. If the analysis of the hSess object indicates a superuser login to the test automation application, then the Delete operation is completed based on the machineID value set in the TSM servlet prior to the invocation of the delete method in Listing 6; otherwise the implementation in Listing 7 executes. The implementation in Listing 7 forms the delete format key (Table 2) required for retrieving the boolean string permission to complete the required Delete operation, and performs the Dlete operation based on the value retrieved from the hSess object. Any error encountered during the execution of software security layers is added to the Java StringBuffer variable errMsg instantiated in the TSM servlet and passed as a parameter to the constructor of RowComputer.java. The error messages stored in the Java StringBuffer variable errMsg is then displayed by TSM to the user of the application, thus providing secure access to the TSM application.
Listing 4. Select operation in the TSM Software Security Layer, RowComputer.java
/** Selectively query the computer table */
public Vector query(HttpSession hSess, int ref, Statement stmt, String whereClaus, String dept) {
ResultSet rs;
String deptList;
String superuser = "";
if(hSess!=null)
superuser = (String)hSess.getAttribute(wn.dept);
if(superuser.compareTo("superuser")==0)
rs = db2h.query(ref, stmt, "Select * from "+ tableName +" where "+
whereClaus);A
else if (hSess == null )
rs = db2h.query(ref, stmt, "Select * from "+ tableName +" where "+
whereClaus);
else if ((deptList = wh.mayReadDept(hSess, tableName, ref, dept)) == null)
return new Vector();
else
rs = db2h.query(ref, stmt, "Select * from "+ tableName +"
where (dept in ("+ deptList +") or (dept is null) or (dept='Null') or (dept='null')) and "+
whereClaus);
return fill(ref, rs);
}
|
Listing 5. Implementation of method mayReadDept
/** Privilege Checking for Read with department */
public String mayReadDept(HttpSession hSess, String tableName, int ref, String dept) {
if(hSess == null )
return null;
StringBuffer sb = new StringBuffer();
sb.append("(").append(tableName).append(")(read)");
String deptList = null;
if((deptList = (String) hSess.getAttribute(sb.toString())) != null)
return deptList;
errMsg.append("Not authorized to Read department ").append(dept).append(" from ").append(tableName)
.append(", ref:").append(ref);
return null;
}
|
Listing 6. Delete operation in the TSM Software Security Layer, RowComputer.java
/** Deletes a row from the computer table */
public boolean delete(HttpSession hSess, int ref, Statement stmt, String dept) {
String superuser = "";
if(hSess!=null)
superuser = (String)hSess.getAttribute(wn.dept);
if(superuser.compareTo("superuser")==0) {
boolean brc = db2h.execute(ref, stmt, "delete from "+ tableName +
" where machineID = " + db2h.xlateSingleQuote(machineID));
return brc;
}else if (!wh.mayDeleteDept(hSess, tableName, ref, dept))
return false;
boolean brc = db2h.execute(ref, stmt, "delete from "+ tableName +
" where machineID = " +
db2.xlateSingleQuote(machineID));
return brc;
}
|
Listing 7. Implementation of method mayDeleteDept
public boolean mayDeleteDept(HttpSession hSess, String tableName, int ref, String dept) {
if(hSess == null)
return true;
StringBuffer sb = new StringBuffer();
sb.append("(").append(tableName).append(")(delete)").append("(").append(dept).append(")");
if(Boolean.valueOf((String)hSess.getAttribute(sb.toString())).
booleanValue())
return true;
errMsg.append("Not authorized to delete from department
").append(dept).append(" within ").append(tableName).append(", ref:").append(ref);
return false;
}
|
Using a test automation application as an example, this article has demonstrated how WebSphere Application Server's HttpSession capabilities can be exploited to secure Java servlet Web applications, at a level of granularity lower than that of the J2EE programmatic security model. By applying the concepts discussed and illustrated here, Web developers and e-business entities can devise and implement similar application-level software security layers to secure their own servlet Web applications.
Appendix: Database table schemas
Class RowComputer v1.22 TableName: computer
The Computer table contains platform entries and specific machines supporting the platform
| Machine | VarChar(64) | >TCP/IP name |
|---|---|---|
| dhcpIndicator | SmallInt Not Null | 1 = Yes 0= No If DHCP network configuration |
| machineID | VarChar(128) NotNull PrimaryKey | Machine key is a mac address or serial number |
| Available | SmallInt Not Null | If this machine is currently available 0 = unavailable |
| Inservice | SmallInt Not Null | If this machine is In Service 0 = manually set Out of Service 1 = inService 2 = not responding 3 = CrossBooted 4 = out of service after testing 5 = brand new test machine from unsolicited source 6 = issue reboot command 7 = Temporarily out of service |
| lastContact | TimeStamp | Time stamp of when the machine last contacted |
| lastUpdate | TimeStamp | Timestamp of the property file |
| outofService | TimeStamp | Time Period in which to put the machine back to in-service status |
| Sibling | VarChar(64) | Machine name of a Dual boot sibling |
| description | VarChar(32) | Description of the machine |
| nickname | VarChar(32) | Nick-name of the machine |
| Location | VarChar(32) | Physical location of the machine |
| Owner | VarChar(32) | Owner of the machine |
| Dept | VarChar(32) | Department that owns the machine |
| ipAddr | Char (16) | IP Address of the machine |
| architecture | VarChar(32) | X86 |
| osName | VarChar(32) | Windows NT |
| silkBill | VarChar(32) | Status of Silk e-mailing and Billing, Need eMail Sent |
| Platform | VarChar(32) | Platform |
| Oshome | VarChar(128) | Operating system home path Example: c:\winnt\system\os |
| silkHome | VarChar(128) | Silk home path |
| scriptTypes | VarChar(128) | Supported Script Types |
| silkServer | VarChar(128) | Silk Server Name |
| testHome | VarChar(128) | Test home directory Example :D:\wastest\wasbuild |
| Userid | Varchar(32) | Target machine user id |
| password | Varchar(32) | Target machine Password |
| washome | VarChar(128) | Websphere home directroy Example: d:\WebSphere\AppServer |
| installPath | VarChar(128) | Websphere install path Example: d:\WebSphere\AppServer |
| nodeName | Varchar(32) | WebSphere node |
| servletPort | SmallInt | Servlet Port |
| wasadminPort | SmallInt | WasAdmin Port |
| buildServer1 | VarChar(64) | First Build Source machine |
| buildServer2 | VarChar(64) | Second Build Source machine |
| buildServer3 | VarChar(64) | Third Build Source machine |
| Update | TimeStamp | Time of the last test update |
| Build | Varchar(32) | Build ID installed in the machine |
| Status | VarChar(64) | Current Status of test in the machine |
| testname | VarChar(64) | Name of the current test |
| vmVersion | VarChar(64) | 1.3.0 |
| vmVendor | Varchar(32) | IBM Corporation |
| userDir | VarChar(128) | D:\Pgm\jCom\Class |
| fullVersion | VarChar(128) | J2RE 1.3.0 IBM build cn130-20011013 (JIT enable d: jitc) |
| tmpDir | VarChar(64) | E:\temp\ |
| osVersion | VarChar(16) | 4.0 |
| userTimeZone | Varchar(32) | America//New_York |
| fencoding | VarChar(16) | Cp1252 |
| userName | Varchar(32) | matey |
| Jhome | VarChar(128) | D:\Java13\jre |
| userLanguage | VarChar(16) | en |
| userRegion | VarChar(16) | US |
Class RowComponents v1.7 TableName components
The Details of Components
| groupname | VarChar(32) Not Null | Component name, Example : Browser |
|---|---|---|
| shortname | VarChar(32) Not Null | Short name, Example : 1 |
| longname | VarChar(32) Not Null | Complete component name, Example : Netscape 6.0 |
| austinName | VarChar(32) Not Null | Austin build platform field : nt |
Class RowBrowser v1.5 TableName browser
This table contains the Browser information various machines
| Machine | VarChar(32) Not Null | Test machine name - foreign Key to Computer Table |
|---|---|---|
| Name | VarChar(100) | Name of the Browser |
| Homedir | VarChar(255) | Path to the Browser |
| installPath | VarChar(255) | Path to Install |
| Startcmd | VarChar(255) Not Null | Full name of the Startup script |
| shutdown | VarChar(255) | Full name of the shutDown script |
| Status | VarChar(255) | Status of the Browser |
Class RowHttpServer v1.4 TableName httpserver
This table contains the location of plugins on the various machines.
| Machine | VarChar(32) Not Null | Test machine name - foreign Key to Computer Table |
|---|---|---|
| Port | Integer Not Null | Communication port of the Http Server |
| Name | VarChar(100) | Name of the plugin ie: IHS or Apache or Go + version |
| Homedir | VarChar(255) | Path to the plugin configuration |
| installPath | VarChar(255) | Path to Install |
| keymanDir | VarChar(255) | Path to the keyman directory |
| Startcmd | VarChar(255) Not Null | Full name of the Startup script |
| shutdown | VarChar(255) | Full name of the shutDown script |
| Status | VarChar(255) | Status of the HttpServer |
Class RowDatabase v1.6 TableName database
This table contains specific database information.
| Machine | VarChar(32) Not Null | Test machine name - foreign Key to Computer Table |
|---|---|---|
| Wasdb | VarChar(100) | Name of the WebSphere Database ie ASV |
| Name | VarChar(100) | Name of the Database ie DB/2, Orcale, Informix |
| Homedir | VarChar(255) | Path to the DataBase |
| installPath | VarChar(255) | Path to Install |
| userid | VarChar(255) | UserID for the Database |
| password | VarChar(255) | Password for the Database |
| Startcmd | VarChar(255) | Full name of the Startup script |
| shutdown | VarChar(255) | Full name of the shutDown script |
| urlName | VarChar(255) | URL name for database connect |
| serverName | VarChar(255) | Server or Machine Name |
| port | Integer Not Null | Port Number |
| Status | VarChar(255) | Status of the Database |
Class RowJDK v1.5 TableName jdk
This table contains JDK Information.
| machine | VarChar(32) Not Null | Test machine name - foreign Key to Computer Table |
|---|---|---|
| name | VarChar(100) | Name of the JDK including Version and Service Level |
| homedir | VarChar(255) | Path to the installation Directory |
| installPath | VarChar(255) | Path to Install |
| version | VarChar(255) | JDK version |
| Status | VarChar(255) | Status |
Ganapathi Adimurthy is a software engineer in the Application and Integration Middleware (AIM) division of IBM in Boca Raton, FL, involved in the design and development of WebSphere Business Integration Adapters (WBIA) for integrating multiple applications. This article is based on his prior IBM work experience with the WebSphere test automation team in RTP, North Carolina during 2001 and 2002.




