02 Authentication APIs

Authentication Framework

Updated by: Susan Bramhall 10/3/01
Originally authored by: Andrew Newman
Yale University
Wikified from the binary Word document and PDF formats.

Introduction

The emerging De facto standard conceptualization of an Internet portal typically requires a mechanism that allows users to identify themselves. At the very least, this mechanism allows stored per-user preferences to be retrieved and applied. In addition, the concept of a session with a corresponding lifespan is presumed. For the purposes of a University portal, we must extend this model to embody several additional features.

  1. The authentication system must be flexible enough to work with a wide range of existing (and future) strong authentication models.
  2. The system must be able to integrate into a University's existing distributed authentication system (if present).
  3. The system must provide features to encourage the development of a single sign on model for the various applications represented by a given portal.
  4. The system must endeavor to foster and support inter-institution authentication.

These goals can be met through the combination of documents (such as this) that provide design guidelines as well as Java classes, interfaces and support packages. This support code takes the form of interface definitions that must be implemented by the developers of backend authentication entities as well as concrete code that is part of the core portal framework. In addition, examples of specific authentication implementations are provided and can be used outright or serve as a guide to those authoring new authentication mechanisms. The uPortal Version 2 Beta provides the following examples of authentication providers:

  1. SimpleSecurityContext - uses a simple md5 hashed password stored in a uPortal database table. Provided by Andrew Newman Yale University.
  2. TrustSecurityContext - checks to see if the user exists in the UP_USERS database table but otherwise presumes to be pre-authenticated by the context from which it is called. The typical system where this might be used is a portal whose main page is protected by HTTP authentication (BASIC or otherwise). Provided by Andrew Newman, Yale University.
  3. JAASSecurityContext - checks a user's credentials using JAAS. Provided by Nathan Jacobs, University of Missouri.
  4. SimpleLdapSecurityContext -checks a user's credentials against an LDAP directory. It expects to be able to bind to the LDAP directory as the user so that it can authenticate the user. Authored by Russell Tokuyama (University of Hawaii)
  5. UnionSecurityContext - acts as a placeholder but considers itself in an "authenticated" state if any of its subcontexts are "authenticated." - Provided by Shawn Bayern, Yale University
  6. CacheSecurityContext - performs absolutely NO validation of the Principal but merely caches the claimed password. We implement this to provide the illusion of single-signon but it comes with significant risk. A channel is able to retrieve the originally validated password of passphrase to perform just-in-time validation but the means of validation is now COMPLETELY in the hands of the channel. If the channel utilizes a weak authenticity-checking mechanism and the password is the same as the one that portal users regard as secure, then unbeknownst to the user, their "secure" password is being placed in jeopardy. PLEASE use this SecurityContext implementation sparingly and with your eyes open! - Provided by Andrew Newman Yale University.

Authentication Life cycle

An authentication object begins life once a single principle associated with the object is identified and optionally verified as authentic. The object's life ends during an operation typically regarded as a "logout" (either active or passive). As such we need to either invent or utilize a pre-existing mechanism to maintain authentication state during the session. The simplest (and currently implemented) approach is to use the Servlet Session object to hold a reference to the authentication object. The advantages of this model are that a Session (HttpSession) object can be counted on to exist and has a semantic behavior that meets our minimum needs. The downside of this approach is that:

  1. The mechanism whereby an HttpSession object is managed varies with Servlet implementation. Some provide a very rich set of tools to manage idle timeouts and hard timeouts where others are less flexible. If we settle on this model and find it lacking (no built, automatic hard logout for instance), we must either write the support code to perform the missing operation or direct implementers to a particular Servlet environment with the feature built in.
  2. The inherent security of this object will be no greater than that of the JVM (see section on JVM security below). Depending upon the sensitivity of the credentials being held, this may or may not be satisfactory.
  3. Crossing the "Java boundary" when implementing legacy channels might be somewhat harder to do given the language (Java) and architecture (JSP/Servlets) centric nature of this solution.

Authentication Objects and Mechanisms

The proposed authentication mechanism for the portal project will require Java classes that implement the four following interfaces and proceed as follows:

  1. The authentication JSP and authentication service class retrieve the claimed identity of the person performing the authentication, instantiate a class implementing the "Principal" interface, acquire the claimed user's credentials and use them to instantiate a class implementing the "OpaqueCredentials" interface.
  2. A class implementing the interface "SecurityContext" will be instantiated and a method with the signature:
    SecurityContext
        void authenticate(Principal, OpaqueCredentials);
    
    is executed.
  3. A method with the signature:
    boolean isAuthenticated();
    is executed and if the result is "true", then the layout object and the individual channels for the portal session are instantiated. The choice of security provider is derived from a properties file. Secondary security contexts may be registered in a chain off the initial "SecurityContext" object.
  4. The parent SecurityContext channel iterates through the chained security context objects and call the authenticate() method of each.

The process of authentication creates three additional objects per security context that are referenced through the security context. These are:

  • A new "Principal" object that may or may not contain the same information as stored in the created "Principal" object used for identification above.
  • A new "OpaqueCredentials" object that may or may not contain the same information as stored in the created "OpaqueCredentials" object above.
  • A new object implementing the "AdditionalDescriptor" interface (see below).

The Principal Interface

This interface can be described as:

Principal
public interface Principal {
    public String getUID();
    public String getGlobalUID();
    public String getFullName();
    protected void setUID(String uid);
}

The string value manipulated by get/setUID represents a "userid" or "username" that is sufficiently specific to be unique within the context of the portal. the GlobalUID referenced above is a version of the same but with enough additional information to be considered globally unique. For example, the network identifier "newman" is sufficient within the Yale portal to identify a single user. Since the authentication would be done against a Kerberos realm, the result of getGlobalUID() in this case would return newman/@NET.YALE.EDU". In an LDAP/X.500 environment the UID might be either the UID= or CN= field where the GlobalUID would be the entirely specified distinguished name (LDAP) or Subject field of an X.509 certificate. (Note that GlobalUID was incorrectly changed to an integer in the uPortal Beta and needs to be reinstated as originally intended in order to enable future cross-realm authentication.)

The OpaqueCredentials Interface

This interface can be described as:

Opaque Credentials
public interface OpaqueCredentials {
   public void setCredentials(byte[]);
   public void setCredentials(String);
}

The intention here is provide a set of cover functions to allow the storage of some data used to verify the identity of the principal. One important aesthetic here is that the object implementing this that persists for the life of the session should not store credentials that are no longer needed after the initial login. For a simple password based authentication, the password (for instance) should not be kept after it is verified as correct. On the other hand, in the case of a Kerberos environment, the resulting decrypted ticket granting ticket might be kept in a persistent object implementing the OpaqueCredentials interface. Another concrete example might be the pass phrase used to decrypt an RSA private key. This should not be kept around but the decrypted private key might be kept around. On the other hand, if the private key is only used once to immediately establish a set of session working keys (as in Secure Sockets Layer or Internet Key Exchange) then even the private key should be destroyed after the session keys are established.

The AdditionalDescriptor Interface

This interface has no required methods and is merely a "marker" interface (like Serializable). The purpose of this is to provide a spot to store additional information that is idiosyncratic to the authentication mechanism or came "for free" with the authentication records. One example of this are the Unix UID and GID vectors associated with a typical Unix login. Another is the collection of various attributes and characteristics typically associated with a PKIX profiled X.509v3 certificate. It is important to recognize that some of these additional attributes have a native access control use (group affiliation under Unix for instance) within their native systems. In the portal model however, these attributes may be algorithmically mapped to portal access control roles but may not be used as access control tokens themselves. The reason for this is that the ACL mechanism would then be forever tied to a particular authentication flavor.

The SecurityContext Interface

This interface can be described as:

SecurityContext
public interface SecurityContext {
    public int getAuthType();
    public String getChannelAffiliation();
    public void authenticate(Principal, OpaqueCredentials);
    public Principal getPrincipal();
    public OpaqueCredentials getOpaqueCredentials();
    public AdditionalDescriptor getAdditionalDescriptor();
    public boolean isAuthenticated();
    public SecurityContext getSubContext(String);
    public Enumeration getSubContexts();
    protected void addSubContext(String);
}

This is the main interface that drives the authentication mechanism and allows channels to add security contexts that must be resolved at authenticate time. Some of the aesthetics of this interface require further discussion. The integer value returned by getAuthType() should be a globally unique authentication flavor. One possibility is to use the SASL names for authentication. It is important, for instance that if we agree that:

public static final int PASSWORD_AUTH = 0x44;

The concept of PASSWORD_AUTH is clearly documented and no one else uses either the number or the name for a different flavor of password-based authentication. The concept of channel affiliation allows credentials to be stored that will be used by channel-specific authentication. (See single sign on below). If there are no additional authentication descriptors or no stored opaque credentials, the value returned from these methods is allowed to be null and the caller must check for this before continuing.

Single Sign on

The promise of single sign on has been an illusive goal for some time now. In the context of the portal environment, a purist would claim that we should either take advantage of a pre-existent single sign on model that all applications have subscribed to or suffer if it is absent. A more flexible approach presented here is to "dummy up" the single sign on by acquiring all credentials needed at portal session startup. Each channel can register a security requirement but the credentials must all be resolved at one time. For example, in a simple world we might have two security domains that each require a pass-word and by convention both use the same password. In that case, one is chosen as the authentication system for the portal session and any channels that use it get it "for free". Channels that use the other security domain request that the same password be used to acquire these credentials at the same time. The credentials might be something like a Kerberos TGT or they might be a Connection handle to an Oracle database account accessed with a password. As mentioned above, all effort to avoid storing the actual password should be made.
The engineering of the channels will be a classic "meet in the middle" approach whereby enough channelspecific code must be written to meet the guidelines above but the application vended by the channel will (hopefully) not need to be rewritten to use a non-native authentication mechanism. This may occasionally fail for particular closed-architecture systems. A last ditch effort that fits into this framework but is not specifically accommodated with support code is to use the single sign on password to unlock a server (LDAP or other) that vends credentials for other systems. This would provide the appearance of single sign on at a substantial cost in lower security. In general systems like this are often like a house of cards where a single vulnerability causes cascading vulnerabilities.

Java Virtual Machine and Security

One topic that must at least be mentioned is the risk of using a JVM to store sensitive security-related information. A single JVM today has no concept of trusted paths, system-level security descriptors or anything like system virtual memory protection. Because of this, all threads executing in a single JVM should play nice together since they will likely be able to access each others' data. The Servlet environment has the ability to separate Servlet (or JSP) based applications into. Separate ServletContexts to avoid namespace overlap but this shouldn't be regarded as a security perimeter per se. At the very least, the Servlet/JSP runtime that vends the portal and its channels should be configured to run in a dedicated JVM until such time that the technology allows JVMs to support strong security internally.