The buzz on security these days centers on topics like Single Sign-On (SSO) and Lightweight Directory Access Protocol (LDAP), but these are really only a piece of the puzzle, the authentication piece. This simply identifies that users signing on are indeed who they say they are.
Even more difficult is the authority piece, which decides how much access a given user gets—to every piece of data on the system! How this works depends on the operating system and can be as simple as "all or nothing" or as sophisticated as the object-level granularity of OS/400 and i5/OS. And note that this is just the object-level security; database security at the row and column level is something entirely different yet again.
MC Press has done a number of articles on security, including ones specifically devoted to the various authentication strategies. In this article, however, I want to focus on defining authority for Web applications.
Who Am I?
The first issue, though, is still authentication. While I won't spend much time on the various authentication mechanisms, I do have to touch on them because, without authentication, authorization is meaningless, while at the same time the authorization scheme has a lot to do with how you authenticate. And the most flexible methodologies may not always be the flashiest. Web application authentication is definitely one of those cases; while SSO is the current hot topic in security today, SSO is not a universal panacea. It can be a great administrative help in some environments (for example, server farms), but it doesn't address the larger issues of B2B and B2C, the areas where Web applications tend to live.
What Issues Are There?
The majority of enterprise-level issues have to do with the differences between authentication and authorization, which can be especially significant in the Web environment. In fact, in some situations it is possible for a user to switch between different authorization levels within a single browser session, and that requires something a little more sophisticated than an SSO scheme.
A typical situation is when a Web application allows both anonymous and authenticated requests, as in a standard B2C environment. Despite the "anonymous" tag, any session with back-end logic on the iSeries needs to run under some user profile, so you'll need some way to map an anonymous session to a given user profile.
And for B2B environments, it can be very unproductive to have to create individual user profiles for every user who logs in. Especially in situations where the duty of user maintenance is delegated to the partner, it is much easier to allow the partner to add new entries (user ID/password combinations), all of which share a common iSeries user profile. Programs can be written to capture the current Web user information and store it when necessary along with the user profile.
Typical Applications
Let's look at a couple of typical applications. In a B2B environment, you typically need to log in as a specific user to get authorization to various functions, such as order entry and AR inquiry. In general, the job stays locked to the same user ID for the duration of the session. However, depending on your business, you may have more than one Web user ID associated with the same user profile on the iSeries. For example, you might assign one profile per customer and allow customers to maintain their actual Web users.
B2C applications require even more flexibility. One such application is order tracking. Nearly anybody who ships things needs a way to provide tracking information. For some companies, this may be as simple as providing a link to the UPS Web site. Others, though, may have their own tracking information, and displaying that information requires a Web application. However, you don't necessarily want people to have to log in to track an order; the less work they have to do the better. On the other hand, an anonymous request may be limited in the information it provides, and only authenticated users may be able to retrieve sensitive information. This means that you need to somehow attach an existing browser session first to unauthenticated (anonymous) data and then later seamlessly connect to authenticated data. This is no simple task.
Implementation Options
So how do you manage this scenario? Over the years, I've seen a number of techniques, but they really break down into one of three categories: profile swappers, session profile jobs, or application-defined security.
Profile Swappers
Profile swapping uses the system API QSYGETPH and its relatives to swap between user profiles during a job. This is really the only choice for situations in which a single job processes requests from multiple sessions. I don't like QSYGETPH because it has some technical shortcomings: The number of handles that can be generated are limited, spooled file support can be cumbersome, and even auditing and triggers get a little confused. These issues have slowly been addressed from release to release, but the added complexity of the profile swapping concept can be a stumbling block.
The profile token is a more intriguing technology. A fairly new concept introduced in V4R5 (see the API QSYGENPT), profile tokens have a little more flexibility and a little more utility than a profile handle, and if I'm not mistaken can even be passed from one job to another for authentication purposes (a profile handle is only usable within the job that created it). Tokens have special features, such as a once-only use attribute and a flag that determines whether the token can be used to generate other tokens. These features make tokens especially useful for passing authentication information between tiers.
The primary advantage of either of these techniques is that you can handle literally any configuration of user profiles by simply changing the job to effectively be running under another profile. You can switch between "authenticated" and "anonymous" sessions by simply changing the effective profile to a predefined "anonymous" profile. On the other hand, since the idea is that one job services multiple clients, storing and retrieving any sort of state information requires more work than in other techniques.
Session Profile Jobs
If each session has its own job, life gets a little easier. In a B2B application in particular, it makes sense to have a single job with a specific user profile for the life of the job. When users log in with their Web user IDs and passwords, the Web user ID is used to identify a user profile, which is then used to submit the job.
In the simplest session profile architecture, one job is in charge of initiating all client/server requests. The client requests a support function and passes in the Web user ID requesting the function. Then, the job controller decides whether the request is valid or not and if it is, submits a job under the appropriate user profile. Note that this profile does not have to be the same as the Web user ID, and in fact in most cases it should not be. Web user IDs should be long and descriptive, with strong passwords.
This approach has several advantages. First, each client session (typically, a browser session) gets its own job. In this manner, the system job load looks similar to a standard interactive environment. Instead of one job in QINTER for each interactive user, you have one job in a batch subsystem for each browser session. You might think this uses up more memory than a queued server approach, but since i5/OS is designed to allow the sharing of programs between jobs, you can have 100 jobs using the same order entry program without wasting memory.
There are other advantages from a pure application design standpoint. For example, with one service job per session, a long-running request does not hang all the jobs in the system. When you route all calls through a single server, if that server crashes or hangs, it hangs up all the other jobs queued up for it, whereas when each session has its own job, one can't hang the other (except through record locks, but that's a different issue). Also, you can use the standard HTTP challenge to handle your authentication; the session is assumed to be allocated to a specific Web user ID for the entire time the session is attached.
Debugging is also more productive, again because holding up a single server job doesn't stop all the other jobs in the system from running. So you can start a service job on a session server and set breakpoints and so on without affecting other users, something that would be a lot more difficult in a queued single-server approach.
You do have concurrency issues, but that's no more complicated than the same issues we run into writing interactive programs. Use an appropriate record locking technique and make sure you have a way to handle cleanup if a job aborts or the user disconnects. More importantly, you have automatic support for stateful sessions. Since each session has its own job, you can do things like create cursors and leave them open between user requests, or position logical files and simply read the next block of records. You can even take advantage of QTEMP and create temporary tables and data areas without fear of collision with other sessions.
Application-Defined Security
This technique requires the most work, and at first glance might seem like reinventing the wheel, but it is the most powerful. It combines the abilities of a session profile job with the flexibility of the profile swapping technique—but at the price of requiring that you handle all your own security.
In short, the idea behind application-defined security is that you provide all the challenge and validation logic. Your Web sessions are always unauthenticated, and each session starts out with no associated user (or more precisely, the user is a default anonymous user). Note that I am not suggesting a stateless session: Each session is still persistent and requires that a job be submitted. However, this job has no intrinsic user profile associated with it other than a generic profile associated with the overall application. Instead, an internal job state variable is used to hold the Web user ID, and this value starts out at blank. At any point in the application, you can choose to challenge the user for a Web user ID and password and then authenticate that information however you choose to. Once authenticated, the Web user ID is stored in the job state variable.
Your business logic then must be written to incorporate this Web user ID in all of its processing. In practice, this isn't actually such a bad thing because for the most part i5/OS is pretty lax in row- and column-level security for database access, so you need to put that code in yourself no matter what. As to application-level security, this gives you an opportunity make fine-grained authority decisions, including factors such as time, day of week, IP address, and so on in addition to standard i5/OS authority.
In practice, this means a user can go to your primary Web site and request an application function anonymously, receive results, and then in the same session, log in, rerun that application function, and receive more detailed results based on the Web user ID. And you can still have functions that will only run in "authenticated" sessions; if the user isn't logged in, you just go right to the login screen, and if the user logs in correctly, you can then pop back into the appropriate program.
Considerations
About the only real benefit I can see from profile swapping is the fact that you can conceivably put extra server jobs into play if you need to provide more oomph to a given function. Also, you can probably distribute the workload to multiple machines a little more easily, but that's more of a server farm issue than a consolidated business server design.
The appeal of session profile jobs in B2B environments is pretty straightforward: You get to use all the wonderful security features of i5/OS without any real additional overhead. You need to create one uber-profile that can submit jobs under any other profile and then make sure that the request submitter (and only the request submitter) runs under that profile. (Note: Please be sure that this profile cannot be used to log on; create it with no password, and make sure any exit programs you have disallow the use of this profile for pretty much any use other than submitting other jobs.) Unfortunately, the requirement that a user provide a Web user ID and password before performing any functions makes that technique too restrictive for B2C sites.
The final approach of application-defined security is the best design for B2C, as long as you're willing to do the security programming yourself. As I pointed out, though, most packages need to have this sort of security logic anyway. You don't want Customer A looking at Customer B's data, so some sort of row-level security is required. You don't want shipping dock workers to change pricing information, so column-level security is required as well. So as long as you have a decent authentication methodology in place, the rest of the code is standard application programming. The good news is that you can use the same validation list concept that you use for HTTP authentication to also provide authentication for your application. On the iSeries, HTTP authentication is done through a validation list, and APIs exist to allow you to maintain and also authenticate against these lists (look for QsyVerifyValidationLstEntry, among others).
Also please note that none of these approaches either require or disallow the use of HTTPS (secure HTTP sessions). It's highly recommended that you implement HTTPS for any sort of secure transactions, but that won't change your choice of authentication mechanism.
This has given you an introduction into the world of multi-tiered authentication and authorization; this is the first step toward building robust, secure Web applications.
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. Joe is also the author of E-Deployment: The Fastest Path to the Web, Eclipse: Step by Step, and WDSC: Step by Step. You can reach him at
LATEST COMMENTS
MC Press Online