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?
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.
Nice work. I appreciate your illuminating commentary on the more convoluted aspects of WLS.
Question: In WLS 9.1, do you know of a general way to determine if the “current user” is acting in a particular role? By general, I mean it does not require that the caller is a servlet or EJB.
I really want to create a Spring-managed SecurityService with a method like this: isUserInRole(String roleName).
This service class can be invoked in any java code — utility class, domain object, servlet, ejb, etc. And magically it can check the current user’s roles against the rolename provided in the parameter.
BEA’s stellar support staff has not found anything for me including MBeans (which I was certain would provide what I need). The veiled comment was that BEA’s oen WLS console app uses secret techniques to access the role info.
Thanks!
Comment by John Lindwall — May 17, 2006 @ 8:13 pm
John,
Thanks.
Roles are going to be very hard to get. Would group membership be satisfactory? If that’s the case, the proprietary weblogic.security.Security class can help. It has a getCurrentSubject() method where the returned Subject has the groups to which the user belongs. You can get the same information by querying the MBeans but the Security class way is so much easier.
Getting back to roles… The problem is that they are dynamic based upon the resource the user requested and sometimes other factors such as time of day. There is no static mapping of a user to a role. Instead, role mapping providers implement the RoleMapper interface. It has the following method:
Map getRoles(Subject subject, Resource resource, ContextHandler handler)
Given a Subject (user) and what the user accessed, the role mapper can tell which roles apply. From what I can tell, there is no way to access the getRoles() method from the role mapper MBean. Besides, utility classes would have no way of re-constructing the resource.
You mention trickery in Console… I don’t know of any place in Console that shows roles that a user has. Is there such a place?
Mike
Comment by Mike Fleming — June 3, 2006 @ 10:10 pm
Thanks for the reply!
Funny, but I ended taking the same path you suggested — base the decision on group membership vs role. This will work well for us since we are not yet using any of the fancy dynamic role-determination stuff (i.e. “Is time of day between x and y and creepy parameter check stuff passes muster”). We use the MBean to check the group membership but I’ll also check out the Security class idea you have suggested above.
I appreciate your explanation of the issue; BEA support was not as concise or informative.
Regarding the console, no I do not know of a screen to show me the roles a user has. Here is what the BEA Support told me:
“The MBeans generally support anything you can do through the console. However, the difficult and hidden parts are the J2EE specific things like isUserInRole(), isCallerInRole(), etc.
The RoleListerMBean may help here.”
Comment by John Lindwall — June 13, 2006 @ 12:44 pm
John,
Thanks for following up.
LOL. I’m guessing they didn’t even look at the method signatures of RoleListerMBean. Nothing there about the roles a user has…
Mike
Comment by Mike Fleming — June 13, 2006 @ 8:26 pm