Denis Pilipchuk looks at JAAS' incomplete integration with Java EE And SOA, and assesses future directions for JAAS.
Conflicts bewteen JAAS and Java EE
Java Authentication and Authorization Service (JAAS) should unify security approaches in Java applications, but it has never integrated very well with Java EE, particularly where representing users is involved. Denis Pilipchuk looks at the current situation, the compounding issue of SOA, and assesses future directions for JAAS.
As Service-Oriented Architecture (SOA) is now slowly starting to change its status from a buzzword associated with boxes on drawing boards, the early adopters are beginning to look beyond primitive examples of service orchestration. One of the first questions they are immediately faced with is providing a common security model for their heterogeneous services. Many enterprises with heavy investments into Java technologies have already developed sophisticated JAAS -based security stacks, both on Java SE and EE platforms. Therefore, the task at hand is to define ways for taking such JAAS-based security services to the next level, to help in linking SOA services.
As JAAS technology has been around for a while now and has seen a lot of coverage, it does not make sense to repeat its strengths and weaknesses in this article in great detail. However, some overview is necessary to appreciate the current situation in the industry and to determine future directions. Before diving into it, however, I would like to express my thanks to Neil Smithline, WebLogic Server Security Architect, who provided many valuable insights for this article.
Brief History of JAAS
JAAS had its debut quite a few years ago as a low-level API for adding flexible authentication and then authorization services to Java SE. Initially bundled as an optional package, it has since become a standard part of the platform, augmenting its static standard code access permission (CAS) policy model with dynamic user-based permissions.
The new possibilities prompted a lot of excitement in the Java community, even though the API itself is quite clumsy and not easy to use. Overall, JAAS appears to have been designed with client-side development in mind, although it has quickly found its way to the server side as well. In particular, its stateless nature and callbacks mechanism as well as a more general lack of higher-level API hiding the implementation details make it hard to integrate into server-side applications. Still, even with these drawbacks, the power of the new technology was quickly appreciated and it was readily accepted by the developers of newer Java applications.
Issues Around Java EE Integration
Back when it was announced that JAAS was going to be integrated into J2EE 1.3, the expectations were that integration of its user-based policy permission model would greatly benefit the existing user security model in J2EE. Unfortunately, the integration has never really taken place, partially because of disagreement among the leading EE vendors, as well as due to certain EE-specific integration issues.
At the moment, there are three major sore spots in this integration (or lack thereof):
- There is no binding defined for JAAS authentication for a Java EE Servlet authentication mechanism.
- JAAS and EE rely on different representations of a user's identity.
- Permission mapping, and therefore authorization, is not consistent between EE application layers.
Some of these aggravating problems, stemming from the lack of proper integration of JAAS into J2EE, are outlined in the sections below.
One of the greatest integration problems lies in the different approaches to user representation in JAAS and Java EE worlds. Speaking plainly, this is where the integration never really took place, and which has been and still remains the greatest source of incompatibility.
While servlet and EJB API methods (such as
isCallerInRole) deal with plain
java.security.Principal objects, JAAS defines its own class,
javax.security.auth.Subject, which represents a collection of principals. Their relationship is reflected in Figure 1.
Figure 1. Relationship of Subjects and Principals
Unfortunately, the relationship and conversion rules between these two different representations have not been specified in either direction. This means that, given a
Subject, a Java EE container will use a vendor-proprietary algorithm for selecting one of its
Principals to use in the EE API. And, given a
Principal, there is no standard way to retrieve the associated
Subject for it to use in the JAAS API.
To illustrate the differences, BEA WebLogic attaches objects with proprietary
WLSGroup marker interfaces to identify principals and groups within a Subject and to know which
Principal object should be used for J2EE methods. IBM WebSphere, on the other hand, adds an object implementing
WSCredential interfaces for the same purpose.
Going back from a
Principal to its associated
Subject exhibits even more provider-dependent behavior. There are two main approaches to do this, and neither of those has been standardized:
Subject on demand, using available
Subject along with the call.
First, let us look at the issues around regenerating the Subject using some kind of app-server-specific identity assertion mechanism. Both WebLogic Server and WebSphere include facilities to perform this kind of operation. The greatest problem with doing it this way is that, unless the principal object is augmented with non-standard metadata, not all of the information from authentication time will be available for the asserter. In particular, this leads to the situation when the sets of
Principals, representing groups and roles, may be different between
Subjects generated by the assertion and authentication modules of the app server, with corresponding side effects for user-based security. For example, a
Subject, which is built by an identity assertion module based on the group information in a SAML assertion, received earlier from a merchant site for the given
Principal (which includes
Principal objects B, C, and D), will likely be quite different from the group information pulled from the internal database (which includes
Principal objects A, B, and C), as reflected in Figure 2.
Figure 2. Recreating Subject (click for a full-size image)
The second approach for retrieving the associated
Subject consists of either caching it, or implementing some kind of
Subject propagation scheme. It should be pretty obvious that both of these options again require highly proprietary implementations. Caching behavior is by definition unique for each app server, so it is never guaranteed (unless the cache is turned off entirely) whether the returned Subject will be the previously cached one or it will be regenerated. Propagation refers to passing the
Subject along with the call context, usually when a remote call is involved. In this case, it is up to individual app servers on both sides to package the
Subject up on one side, and unpack and convert it back into a Java object on the other. WebLogic Server, for example, works differently depending on which communication protocol is used, even if the call takes place within the same WebLogic Server domain. If it communicates using a proprietary T3 protocol to another instance of WebLogic Server, then the
Subject is passed and recreated on another side; otherwise (for example, when using IIOP, or connecting to another AppServer), only the username of a
Principal object is available at the receiver, as prescribed by Java EE specifications.
Directly related to the problems around
Subject propagation is the user policy issue. If the same user may be associated with different
Principal sets contained in multiple
Subjects, depending on which part of the system you are looking at, imagine what havoc it wreaks for authorization policies. Consider the situation, shown in Figure 2: The code, executing on the behalf of the same user, will be assigned different sets of permissions by the authorization policy, since his
Subjects reflect different sets of groups and roles. This situation is illustrated in Figure 3. Continuing with the earlier example, it is possible for the same user in an EE-based enterprise application, when represented in one of the application's components by Subject 1 (with
Principals A, B, and C), to be granted permissions PA, PB, and PC, while in another component, with Subject 2 (
Principals B, C, and D) to be granted permissions PB, PC, and PD.
Figure 3. Different permissions (click for a full-size image)
This is actually a symptom of a larger problem: Since J2EE does not define a mapping from roles to user principals, it is also impossible to perform mapping to user permissions in an interoperable way (that is, there is no standard path Principal->Role->Permission Set). This makes any static analysis of authorization policies dependent on the vendor-specific tools. As a result, this lack of standardization of approaches to authorization policy configuration hinders security audit efforts, required for satisfaction of regulatory requirements for many enterprise-class applications.
The second authorization issue, introduced by the lack of proper integration of JAAS into both J2SE and J2EE, has also been known and discussed for a number of years, but nothing has changed. First, after introducing JAAS into J2SE security architecture, the
doPrivileged method of
java.security.AccessController was not updated, which led to cutting off the current
Subject.doAs calls. Now, since J2EE places a requirement to propagate the current call
Principal from servlets into EJBs, the runtime behavior is undefined, as shown in the Figure 4.
Figure 4. Effect of doPrivileged (click for a full-size image)
Correspondingly, app server vendors came up with different solutions to address this issue, and these, of course, are incompatible with each other. IBM introduced a special type of
doAsPrivileged methods restore the real
Subject and call the EJB with the appropriate identity. WebLogic Server, on the other hand, used a two-stack approach, where it maintains two
Subject stacks at runtime—one for Java EE, and another for SE identities, as demonstrated in Figure 5.
Figure 5. Two identity stacks in WebLogic Server
Future Directions for JAAS/J2EE Integration
To address authentication and authorization issues around integration of JAAS into J2EE, there are two JSRs: 196 and 115 . They are quite far away from each other in terms of their readiness; while JSR 115 has been finalized and goes through maintenance releases, JSR 196 had been pretty dormant for years, until it suddenly showed some life signs last year.
Let's start with SR 115, since it is a "done deal." It is important to note that it has provided the necessary foundation for inclusion of JAAS user-based permissions into the general framework of Java EE. What it failed to achieve, however, is specifying a vendor-independent configuration mechanism, that is, each app server provides its own proprietary mechanism for configuring those EE user permissions.
JSR 196 has been going through a significantly more difficult process. This is not very surprising, given that there are significant disagreements between the member companies about the way to proceed, because each of those companies has already integrated JAAS into its EE container in a proprietary way. At this point, this JSR will not be able to catch the Java EE 1.5 train, and it is not clear which delivery vehicle will be available to it and when it will see daylight.
The current draft of JSR 196 at least makes an attempt to address two of the integration problems listed earlier:
- The Servlet profile should standardize the way of binding JAAS authentication into Java EE Servlets.
- The suggested mechanism of using a Designated Principal callback should provide an interoperable way for the JAAS Login Module implementers to enable unambiguous selection of a
Principal object for propagation of user identity in J2EE calls.
Influence of SOA
As has been described in the previous sections, JAAS has had a rocky relationship with Java EE since the beginning. Given where it is right now, how will it be affected by the introduction of the SOA paradigm?
It is clear that not all of its concepts will be very usable or applicable at all in the world of distributed services. The authorization model will be affected first. As it stands now, the Policy Decision Point, or PDP (Java user policy) and Policy Enforcement Point, or PEP (Java
AccessController) are located next to each other. When a system is composed of multiple services, each of them will likely have its own PEP, unless they share the container. However, in order to provide consistent authorization, the PDP should be centralized and affect the entire system, as shown in Figure 6.
Figure 6. PDP changes (click for a full-size image)
The effects of switching to the SOA model for JAAS authentication are not as drastic, but some updates are required for that area as well in order to handle the new demands. In particular, they are needed for
Principal representation and propagation (yes, again), and for methods of gathering authentication information, since those Java callbacks are not going to work too well for SOA.
width="1" height="1" border="0" alt=" " />