Covering J2EE Security and WebLogic Topics

WebLogic Security Framework Overview

I’ve mentioned the WebLogic security framework in the following posts:

However, the discussion detail was either from low earth orbit or zoomed in on a particular plugin, neither of which suitably covered the framework. Since I plan on talking more about the security framework, now is probably a pretty good time to have a look at it as a whole to see how it can meet your needs for application security.

The WebLogic security framework was introduced in WebLogic 7 and continues relatively unchanged in WebLogic 9. The framework provides a modular, plugin-based approach to handling the typical needs of application security. This modularity enables third-party providers and developers alike to create custom plugins for functions such as authentication or authorization. I’ll talk more about plugins in later.

Security Aspects of the J2EE Specification

The security framework is WebLogic’s implementation of the security aspects of the J2EE specification. As a result, it provides container-managed security features for your applications. This is significant because you may not have to write any security code in your application. Instead, you declaratively define security constraints on your resources (such as web pages or EJBs) in XML files and then let WebLogic intercept user requests to ensure that the user is authorized for access.

The container-managed security notion is from the J2EE spec, but the security framework allows for flexible configurations that don’t break the spec. That’s important because it leaves you breathing room for implementing custom security functionality while continuing to work within the confines of the spec.

Adhering to the J2EE specification buys you several things. They are:

  • Standard declarative security definitions for protecting resources
  • Standard programmatic access to the name of the authenticated user
  • Standard programmatic access for checking a user’s roles

Because these things are standard, an application you write today that uses these techniques will run unchanged on JBoss, WebSphere, WebLogic, or whichever application server or servlet engine you care to mention assuming that it adheres to the J2EE spec.

The programmatic security access methods for web applications are:

  • HttpServletRequest.isUserInRole(roleName)
  • HttpServletRequest.getRemoteUser()

and the programmatic security access methods for EJBs are:

  • EJBContext.getCallerPrincipal()
  • EJBContext.isCallerInRole(roleName)

Of course, these calls only work from within servlets (which includes JSPs) or EJBs, respectively. POJOs need not apply. However, WebLogic provides a proprietary way to get the user anywhere within the thread of a request. You can do this by calling weblogic.security.Security.getCurrentSubject(). You may also find weblogic.security.SubjectUtils.isUserInGroup(subject, group) useful. Just keep in mind that these two tricks are proprietary and won’t work in other servers.

You can find more information on declarative and programmatic security at http://e-docs.bea.com/wls/docs81/security/index.html.

The Framework

The discussion so far has been mostly about how the WebLogic security framework implements the security part of the J2EE spec. Now we can turn our attention to the actual components of the framework that make it all possible.

As I mentioned before, the security framework consists of a group of plugins which handle the various aspects of security. I purposefully used the term “plugin” to drive home the point that the framework is a pluggable solution. However, BEA refers to these components as Security Service Providers so I’ll use the term “provider” for the rest of this post.

WebLogic 8.1 comes with the following provider types:

  • Authentication
  • Identity Assertion
  • Role Mapping
  • Authorization
  • Adjudication
  • Credential Mapping
  • Auditing

Authentication providers are responsible for verifying the user’s identity. For example, an authenticator could authenticate based upon a username and password. You can have more than one authenticator at a time. You can also control both the order in which authenticators are accessed and the behavior of the authentication process with multiple authenticators by using the JAAS control flags (OPTIONAL, SUFFICIENT, REQUIRED, and REQUISITE).

Identity assertion providers are closely related to authenticators but they authenticate a user based upon a perimeter token that was attached to the request. For example, an X.509 certificate or a SAML token are examples of perimeter tokens. The significance here is that the user was authenticated by a different system and the token is a by-product of that authentication. Thus, the user is authenticated indirectly. You can have multiple identity asserters as long as each one handles a different token type.

Role mapping providers associate roles to the authenticated user. These roles can be dynamic based on the username, group, or time. You can have multiple role mappers.

Authorization providers grant or deny access to a resource by comparing the user’s roles with the resource’s security constraints. You can have multiple authorizers. Each authorizer can vote PERMIT, DENY, or ABSTAIN. Making a final authorization decision is left to an adjudicator.

Adjudication providers consider the votes of the authorizers in making a final authorization decision. For example, the adjudicator might be set to require all authorizers to vote PERMIT before access is granted. Or, one PERMIT vote and two DENY votes might be sufficient for granting access. It’s all up to the adjudicator, of which there can only be one. Otherwise, you’d need an adjudicator adjudicator. 😉

Credential mapping providers are for mapping an authenticated user to credentials suitable for accessing a back-end system via a Resource Adapter.

Audit providers allow for logging of security events managed by the other providers. You can have multiple auditors and you can set the severity level of events to log.

All of these providers are configured in a security realm within a domain. The realm also includes users and groups. These are the users and groups accessed by the providers defined in that realm. You can have multiple realms defined in the domain but only one realm can be active at a time. Changing the active realm requires a server restart.

The default realm configured in a WebLogic domain contains a group of providers that act against the embedded LDAP running within WebLogic. While it’s not suitable for production use, this LDAP server contains the WebLogic administrator user, standard roles, and standard groups out of the box.

Along with the default providers, BEA includes many other authentication providers such as Active Directory, SPNEGO, and a host of miscellaneous LDAP authenticators. WebLogic 9 introduces several more providers such as the DBMS providers. In fact, WebLogic 9 even introduces a new provider type: the Certificate Lookup and Validation provider. I haven’t tried it yet but this new provider type looks like a welcome addition.

I’ve painted a rosy picture of the security framework so far, and for the most part it does a great job. However, it does have some weaknesses:

  • Auditing has been a little weak–not in the output of the auditor but rather the control of it. It looks like WebLogic 9 has fixed some of this.
  • Since the security realm configuration is specific to a domain, all applications running in that domain have to use the same configuration of authenticators, authorizers, etc. Essentially, all providers, users, and groups must be suitable across all deployed applications.
  • Being able to configure multiple realms even though only one can be active is something of a tease. I haven’t thought through the implications of this, but wouldn’t it be great if you could specify that an application uses a particular realm? (Update: Now you can. Thanks, Matthias!)

Conclusion

The WebLogic security framework is a flexible, plugin-based mechanism for handling application security requirements. It implements the security aspects of the J2EE spec which allows for container-managed declarative and programmatic security. Finally, if the included providers aren’t sufficient for your purposes, you can create your own or buy third-party providers.