Background

The following section details the logical separation of PortalGuard components. This information is provided because it is crucial for understanding how to best provision PortalGuard behind a load balancer.

Architecture

PortalGuard was originally designed as a cross-platform solution that supported HTTP servers from multiple vendors. Although it now only officially supports Microsoft IIS, it was originally architected with Linux as the target operating system. Knowing that multiple HTTP stacks had to be supported, PortalGuard was designed with very well-defined boundaries between the front end, middle and back-end tiers.

The front-end design leverages HTML and CSS for displaying the user interface and JavaScript for automating it. These were chosen precisely because they are cross-platform and cross-HTTP stack. Although ASPX files are used in the IIS version, steps were taken to limit the use of .NET-specific code. For the most part, ASPX is just the delivery mechanism for vanilla HTML.

The middle tier implements all the logic in PortalGuard and is contained within a DLL or shareable object written in standards-based C++. The only piece that is web-server specific is how this DLL is referenced via a small shim. For IIS, P/Invoke is used to call out to the native DLL from a C# web handler.

The back-end is where all user and configuration data is stored. These exist in either text or XML files on the PortalGuard server’s local file system -OR- in a SQL database. When SQL is employed, ODBC is used to isolate the PortalGuard server from the connectivity specifics of the SQL server.

Action Atomicity

Most PortalGuard actions require multiple round-trips between the end-user’s browser and the PortalGuard web server. For example, a single self-service password reset “action” is actually comprised of the following five discrete steps:

  1. Get username from user, the self-service actions available to the user are returned
  2. User chooses action (e.g. pw reset as opposed to unlock), and the available authentication types for that action are returned
  3. User chooses authentication type (e.g. answer X of Y challenge answers or have an OTP sent to their phone). For challenge questions/answers, PortalGuard returns the questions available to user and the required number of answers.
  4. User submits their answers which are validated by the PortalGuard server. If correct, the returned response causes the “new password” fields to display. Otherwise, the user is prompted to re-answer.
  5. User enters the choice for their new password and the PortalGuard server ensures it is sufficiently complex (challenge answers are checked here again). If not, user has chance to re-enter a new password. Otherwise, the password change occurs and a success code is sent in response.

By sending all the required data with each request, PortalGuard steps are RESTful (link). For example, all data necessary for each PortalGuard action is sent with each request, e.g. challenge answers are sent in both steps 4 and 5 during a password reset. This ensures users do not need to maintain communication with the same PortalGuard server instance over the lifetime of the action.

In its simplest form, PortalGuard can be considered a .NET application because it runs on Microsoft IIS. However, IIS session state and view state are not leveraged by PortalGuard at all which simplifies IIS configuration tremendously as will be seen in the next section. Its RESTful design also precludes the need for load balancing support internally. As such, the middle tier of PortalGuard is not burdened with code or logic specific to supporting load balancing. At the transport level, PortalGuard HTTP traffic effectively boils down to a series of POSTs by the browser and HTTP responses from IIS. The responses in turn drive the user interface.