--Paraphrase of a Benjamin Franklin quote concerning liberty and safety
In my last column, I covered a lot of issues about Internet security as it applies to Web application access--from conversation security to Web pages access. All of that got us to a point where we were actually invoking a Web page on the host using a specific Web user ID.
In this column, I will address the next set of topics:
- Invoking the business logic--how you actually run the business logic once the Web application is started
- Using the toolbox--how to directly call non-Java programs, using the powerful ProgramCall class in IBM's Java Toolbox for the AS/400
- Switching user profiles--how to use the user ID to determine under which user profile the application will run
Finally, I'll explain my opinion on using OS/400 user profiles for Web application authentication. (Hint: I'm not for it.)
Invoking the Business Logic
The previous column covered all the ways you can secure the ability to access a Web page. To be more precise, you're providing access to various URLs within your host, and that also means you're securing access to your Web applications. Whether your application is initiated via CGI program, servlet, or JavaServer Page (JSP), it is initially accessed by a URL. Therefore, the techniques in my last column in effect secure the ability to initiate Web applications.
So, it seems that we're done. And on most platforms, we probably would be done. But on the iSeries, there's one more issue--that of OS/400 object security. No matter how we start up the application, there's still the issue of running the business logic under the correct user profile.
The next subtopic will deal with servlets and JSPs. Since these programs run in the Java Virtual Machine (JVM), they present special challenges when dealing with this issue. If you're running an RPG CGI program, you can skip directly to the section on switching user profiles.
Calling a Program from a Servlet
There are two ways to access data in a servlet: direct database access and program calls. I'm going to assume that you are calling an HLL written in RPG or COBOL to do your work, as opposed to writing your database access in Java. If your program is simply doing JDBC calls to fill up an inquiry screen with publicly accessible data, then security is usually less of a matter and can be handled in other ways. For example, if files containing the public data also have some sensitive information, you can create a public staging library. There are obvious drawbacks here, but in my mind they outweigh the requirement of having passwords in the clear that is imposed by JDBC access. Another topic, another day. However, if you'd like to do a little research on your own, check out IBM's recommendations on security.
I'd particularly direct your attention to the section on data security. While it focuses on CGI and Net.Data, the same issues apply for servlets and JSPs:
"Keep data that you access with CGI programs or Net.Data separate from your production data. If possible, use a separate copy of database files in a separate library. Consider using an intermediate program or stored procedure to update database files instead of giving the Internet user profile direct access."
If you're calling a program, that program is going to need to run under a specific user profile, and this is where things get tricky. To call a program, you should use IBM's Java Toolbox for the AS/400. (Another way is the Runtime.getRuntime().exec() method, but it's less effective for a number of reasons, not the least of which is that it is difficult to pass parameters.) If you are unfamiliar with the toolbox, you really should spend some time getting acquainted with it. There is no better piece of software available for accessing iSeries resources in Java. The toolbox comes free with OS/400, and there is also an open-source project called JTOpen that provides not only a more fully featured version, but also the source for the toolbox. Click here to learn about the toolbox.
So now we're down to a basic architecture: The servlet (or JSP, which is essentially the same thing) calls a program using the ProgramCall class in the Java Toolbox. However, this program will be running either under the default QUSER profile or under the user profile that you specified when you created the AS400 object to establish the connection. While it is possible to write logic allowing you to connect under different user profiles, you will need to have not only the user profiles but also their passwords available in the clear at some point in your program. This is typically something to avoid. So we can assume now that you are calling a program and that that program is running under some generic user profile.
Switching User Profiles
There is a way to change the current user profile for a Web application based on the HTTP logon. However, it only works for users who are authenticated using the OS/400 user profile and password. I prefer not to do this, for reasons outlined in the section below entitled "Using OS/400 User Profiles for Authentication."
If you are not using OS/400 user profile authentication, then whether you got here via a CGI program call or via a servlet using the toolbox ProgramCall class, you are now running an HLL program, and you're doing it under a different user profile than the one corresponding to the user. In order to properly secure your application, you must now switch to the correct user profile. There a number of ways to do this, including adopting authorities, swapping profiles, and submitting jobs to batch.
Adopting Authority
Adopting authority is a standard OS/400 technique to temporarily gain additional authority. A program is called that adopts the authority of the program's owner (to enable this, the program is created with the USRPRF(*OWNER) attribute). In the case of your Web application, you would design a dispatcher program, then have one version of the program for each user profile. Each individual version would then adopt the authority of the specified user profile. You would invoke the appropriate dispatcher program based on the Web user ID, and then the dispatcher program would call the appropriate Web application program, and away you go. The obvious drawback is that you have to have one version for each user profile, which means additional maintenance. A less obvious drawback is that this technique does not change the user profile for any generated spooled files, nor does it log the adopted user profile to things like journals and audit logs. Finally, adopted authority is lost when trigger programs are invoked, so this may be a concern if your application uses triggers.
Swapping Profiles
A second technique is to use the user profile swapping APIs: QSYGETPH, QWTSETP, and QSYRLSPH. The QSYGETPH API allows you to get a "handle" to a user profile. You must specify the user profile, and then either specify a password or have *USE authority to the user profile. Once you have a handle, you can then use the QWTSETP API to switch to that user profile. From this point on, you will be running under that profile. These APIs were specifically designed to support server programming such as that required for client/server applications, and Web applications fall under that umbrella quite nicely. It is very important that you return the handle using QSYRLSPH after you are done; otherwise, you will eventually use up all the available handles.
Care must be taken when designing a program that uses profile swapping. Files that are already opened will not be checked for security, which means you may accidentally allow more access to a user than you had intended. Also, journaling doesn't work exactly as you might think. For example, if you write to a file and the output is buffered, when the data is finally written to the file, all buffered records will be shown in the journal as if they were written by the user profile that was active at the time of the last write. Also be very careful when writing programs that test this technique; remember to get a handle to the current user profile. If you switch to a user profile and do not switch back, you'll return to the command line with only the authority of the swapped profile.
Submitting to Batch
The third technique consists of submitting a job to batch. By submitting a job to batch, we return to the normal world of OS/400 control. A job can submit another job under any user profile to which it has *USE authority. Because of this, it is relatively easy to create a simple dispatcher to submit jobs under any user profile. Not only that, the dispatcher can control many other characteristics, including where the job runs and where its output goes. Job queues, memory pools, time slices, priorities, library lists, output queues, and all the other attributes controlled by a job description are available to the dispatcher.
Submitting a job to batch does require some extra work. You need to be able to communicate with the job. I use data queues for this. There is extra complexity in creating a messaging system to communicate between the Web application and the batch job. There is additional infrastructure design required for submitting the jobs, cleaning up the jobs, and so on. For example, I use the CEERTX routine to register a termination handler. This allows me to notify the Web application if for some reason the batch job is ended prematurely.
Which technique you choose depends on your own requirements. For me, the simplicity of selecting the user profile (the USER parameter on the SBMJOB command) and the straightforward nature of how security is handled makes the batch submit approach the most secure and the most manageable. This security and manageability is worth the one-time cost of setting up the infrastructure.
Using OS/400 User Profiles for Authentication
Since I am such a stickler for getting the correct user profile for my Web applications, you may be wondering why I don't just let OS/400 perform my user authentication for me and then use that user profile for security. While this is a simple way to do things, there are two primary reasons I don't do it: security and flexibility.
For security reasons, I just don't like handing out user profiles and passwords to my iSeries for any reason. By requiring a Web user ID and password that is then mapped under my control to a user profile, I am in effect creating an additional firewall between users and my data. While this is less of an issue for intranet users who may already have user profiles, it becomes more important as you begin to allow Internet access to your machine. You can give a Web user ID and password to a third party with the knowledge they cannot use it to FTP or Telnet into your machine. This is very important, especially when you're setting up access for multiple companies.
Let's take a situation in which you are a distributor with multiple dealerships. The business problem is that you never want one dealership to see the data for another dealership. Let's further assume that your sales data for all dealerships is kept in a common file. In any typical iSeries shop, the user profiles for both dealers will have read access to that file, but under program control they can only access the data for their dealership. However, if for any reason you accidentally allow a remote user to access your machine via FTP, that user can use that user profile and password to read the entire contents of the file. Certainly you should prevent FTP access, but by not giving out actual user profiles and passwords to remote users, you further secure your production machine.
Flexibility is also important. While all of the HTTP and Web application servers shipped with the iSeries allow authentication by OS/400 user profile, other servers do not. For example, the standalone open-source Tomcat server has no knowledge of OS/400 security. So by using OS/400 security, you are limiting your Web server options. If instead you use a non-OS/400-specific approach, you can use a third-party server, such as the open-source version of Tomcat, or even move your Web server entirely off of your iSeries. While there are additional complexities that must be considered, separating your Web server from your production machine provides not only load balancing but also another layer of security. Even if your Web server is compromised, there is no direct access from the Internet to your production data.
There is also one last minor issue that can be addressed by using Web user IDs for authentication: proliferation of user profiles. Let's return to the model of a distributor and dealers. Using Web user IDs instead of user profiles allows multiple Web users from a dealership to all run under the same user profile. For example, the dealer may need access for a number of clerks, but to your application they can all run under the same user profile. In this case, you can easily set up multiple Web user IDs to map to the same OS/400 user profile. Adding a new Web user for the profile is as simple as adding an entry to the appropriate validation list and then adding another record to your internal mapping table. A minor issue, perhaps, but it becomes important for applications such as storefronts, where you may have literally thousands of different Web users. Do you really want to set up an additional user profile for every Internet user?
All of these considerations combine in my opinion to make a strong argument for avoiding the apparent simplicity of OS/400 user profile authentication in favor of a more generic Web user ID approach. Unless you're completely ready to commit entirely to the Apache/WebSphere combination running on the iSeries, you may want to be very deliberate in your choice of authentication and security. Given the somewhat fluid nature of IBM's position regarding Web servers (and their pricing) up to this point, it seems to me that having options is a good bet at this time.
Conclusions
As usual, the right approach is going to depend on your systems, your architecture, your staff skills, and your future goals. There is no pat answer in the Web application development world, and I'd be lying if I told you otherwise. In this particular instance, I think the biggest contributors to your decision should be how much investment you are willing to make in an upfront architecture and how much flexibility you are willing to give up in order to shorten your development cycle.
If you want fast time to market and are willing to give up some security, then I'd opt for OS/400 user profile authentication and be done with it. At the other end of the spectrum, batch submission of jobs using a Web user ID cross reference is the most flexible and most secure approach, both from a development and a work management standpoint, and the time you spend developing a solid messaging architecture for your batch programs will stand you in good stead in your ongoing Web application development. While I cannot choose for you, I hope I've given you enough information to make the right decision for your future.
Joe Pluta is the founder and chief architect of Pluta Brothers Design, Inc. He has been working in the field since the late 1970s and has made a career of extending the IBM midrange, starting back in the days of the IBM System/3. Joe has used WebSphere extensively, especially as the base for PSC/400, the only product that can move your legacy systems to the Web using simple green-screen commands. He is also the author of the popular MC Press book E-deployment: The Fastest Path to the Web. You can reach Joe at
LATEST COMMENTS
MC Press Online