Wednesday, March 31, 2010

WebLogic, LDAP Authenticators, and Groups

The number one cause of mystery login problems that I see with customers using LDAP authenticators (be it OID, Sun, or AD) relates to a problem with the search done to determine what groups the user is a member of.

As part of the authentication process, LDAP authenticators do a search to determine what groups the user is a member of which in turn get used in determining the group memberships and roles for the JAAS subject and principals. If there is a problem with this search, then WebLogic will fail the entire authentication even if the user authentication check (username + password) against the directory was successful. Notice that I said problem with the search and not search failure. If the user simply doesn’t exist in any groups then the authentication will succeed. The issue is with the authenticator not even being able to successfully execute the search.

The group search failure can be cause by a couple different things and can be a very nasty situation to recognize and sort out.

Search Configuration Failures
The more straight forward cause of a group search failure is that the search itself. This can be cause by having a bad “Group Base DN” or “All Groups Filter” in the authenticator configuration. If for example you mistyped part of the base DN or the object class in the filter, then the search will fail to execute. What you’ll see in the logs is a message saying authentication has succeeded then one or more error messages about the group search, and then another message saying authentication has failed.

Problems with Nested Groups
The more insidious cause of group search failures is with nested groups. By default the authenticator will search not only what groups a user belongs to, but will go on to search what groups those groups containing the user belong to and then what groups those groups belong to and on and on…

If there are a ton of groups with lots of nesting, the authenticators can time out just in processing nested groups. However, the bigger or more common issue is that authenticators can get in infinite loops processing two groups that contain each other or certain dynamic groups.

The best way to prevent this is to limit the levels of group membership nesting that the authenticator will follow to build up the JAAS subject and principals. You do this by changing “Group Membership Searching” from unlimited to limited and changing “Max Group Membership Search Level” to the desired level of nesting you want to pursue. Leaving it at 0 will mean that the authenticator will not process any nested groups.

My recommendation is that as a best practice you should almost always switch to a limited search even if you want the authenticator to heavily process nested groups. Setting the level of nesting to something high like 5 will almost always give you all the memberships/roles you need but will limit your exposure to infinite loop situations caused by problems in the directory.

Monday, March 29, 2010

Identity Propagation in a flow involving OAM, OSB and web services

A Sales Consultant asked for my opinion in a scenario where a customer wants to propagate end user credentials all the way from OAM (Oracle Access Manager) to web services responsible for executing business logic.

In the customer flow, after being authenticated by OAM, the end user is redirected to a portal UI. The UI makes calls to OSB (Oracle Service Bus) which in turn invokes web services deployed on WebLogic Server. One of use case driving requirements is that the end user identity should be available for underlying web service implementation so that it can be recorded in database tables for auditing purposes. Therefore, the main question here is how to get the user identity from OAM token and make it available for web service implementation code.

OAM is a web-based SSO solution. Very roughly put, it works by means of an HTTP cookie called ObSSOCookie which is recognized by OAM's Policy Enforcement Points, known as Web Gates. A Web Gate intercepts all HTTP requests for a protected resource and evaluates whether an ObSSOCookie is present and valid, in which case the user is considered authenticated.

OSB is an SOA integration component within Oracle's SOA portfolio. It provides routing, transformation and mediation capabilities for interactions between heterogeneous services.

Ok, to the solution.

Let's first talk about what happens when an anonymous user accesses the protected portal UI page. Anonymous users don't hold an authenticated ObSSOCookie (note that anonymous users might hold an ObSSOCookie, but for the default OblixAnonymous user), therefore are challenged by OAM's Web Gate according to the configured authentication scheme.

Let's assume in this case a form-based scheme requiring username and password is set. When challenged, the user types in her username and password. Assuming those are correct, an ObSSOCookie identifying the end user is generated and added to the HTTP response. The end user is granted access and directed to the protected resource (portal UI page). Once the user lands on the portal UI page, a call is made to a web service running on a remote WebLogic Server via OSB.

At this point we need to make an important decision: how to retrieve the end user identity and move it forward. Remember that so far it only exists within the ObSSOCookie that is present in the HTTP request. There are two ways to accomplish it: Within the portal UI, i) the ObSSOCookie can be added to an Oracle proprietary SOAP header or ii) the end user identity can be obtained from portal application container's Java Subject and added to a standard SAML message within the SOAP header. In any case, an OAM identity asserter must be configured in WebLogic Server running the portal application. OWSM (Oracle Web Services Manager) also plays a vital role from now on. An OAM identity asserter basically asserts the end user identity present in ObSSOCookie against the configured Identity Store in WebLogic Server. If assertion succeeds, the user principals are added to the container's Java Subject.

OWSM is a key component in Oracle's SOA solution. It provides centralized definition and distributed enforcement of security and management policies for SOA and JavaEE applications. OWSM runtime modus operandi is very simple: simply put, agents installed at specific endpoints intercept and evaluate SOAP calls according to rules specified by attached policies. Policies come in two flavors: client-side and server-side. Client-side policies usually add data to the SOAP message while server-side policies retrieve that data and process them, many times delegating decisions to other third-party mechanisms.

Back to our flow, I recommend approach ii) as the means of propagating the end user identity. For two reasons: a) we're avoiding adding proprietary data to the SOAP message. If one decides for i), on the server side she needs to provide for understanding that proprietary data. Even considering that OWSM natively supports it, the implementation would stay tied to necessarily understanding ObSSOCookie. If your organization standardizes on SAML (Security Assertions Markup Language), for example, that might be a problem. b) OAM is unlikely to be available in a development environment, therefore relying on ObSSOCookie would simply not work. Once the ObSSOCookie is asserted, a Java Subject becomes available within WebLogic Server.

By attaching a SAML-based OWSM client-side policy to the calling endpoint, the OWSM agent will pick the principal from the Java Subject, generate a SAML message and add it to the SOAP header.

There are several options on how the SAML message can be generated: as clear-text, with message-level security (WSS) or sent through an SSL channel. I will cover the details of message-level and transport-level security in OWSM in a subsequent article.

At this point we're making a SOAP call and we've added a SAML token to the SOA header. Next element in our flow is OSB. The key point here is that we don't need to process that token in OSB. All that's required is having OSB configured in pass-through mode and the request will get intact to the invoked web service. On the web service, we attach a SAML-based OWSM server-side policy that is capable of understanding the token generated by the client-side policy. The policy extracts the token and submits it for processing, which in this case means asserting the end user identity against the identity store configured for the WebLogic Server hosting the web service. If the user is successfully asserted, a Java Subject is created and made available to running applications. One can use JAAS APIs to get the authenticated user name and stick it into any DML statements that are executed against a database.

Thursday, March 25, 2010

Oracle Access Manager (OAM), SSO and Session Management

The subject for today is understanding user session management in an OAM/SSO enabled web application environment.

Some people think that once OAM is deployed, that the OAM session which is represented by the OBSSO Cookie replaces application or container (app server, .net, PHP etc) specific sessions. This is not the case. Application and container specific sessions still exist. It is just that rather than logging into a specific application to initiate the application or container session, the session will be initiated automatically if the user has an existing OBSSO cookie. Thus, as the user moves from one container or application to another, they initiate new user sessions without having to re-authenticate.

For all its glory, the introduction of OAM creates a few nuanced issues for architects of web applications to navigate:

Session Timeouts
It is important to be aware of the relationship between the session timeout values in OAM and session timeouts for container/application sessions.

OAM sessions have both idle and maximum session timeout controls. Most container/application sessions control only the maximum length of the session.

Ideally, your OAM and container/application sessions will timeout at the same time but it is important to understand what happens if they don’t. Even if your session timeouts are set to the same value, the OAM session can timeout before an application session if a user moves from one container to another in the same OAM session. This is because the 2nd container/application session will have started well after the OAM session.

So, if a user’s OAM session expires before their container/application session, they will be blocked at the web server (or proxy server) by the OAM webgate and asked to re-authenticate. Upon re-authenticating, they will be let through to the application. What happens next depends on the details of the integration between OAM and the container or application.

If a new login to OAM always results in a fresh application/container session then everything will work as you expect.

If however, the existing application session from before the OAM session timeout is still in place then the user of the browser will continue with that session. This is fine as long as the user re-authenticating is the same as the original user. In the case of extranet applications, applications used from shared systems or even just applications that are accessible from the public it is important to put measures in place to ensure that the user associated with the OAM session is the same as the user associated with the application session. See session synchronization below for more on this.

Logouts
If your pre-OAM enabled application has logout capabilities, you will want to synchronize this capability with an OAM logout. OAM logs a user out when they access a logout URI. Logout URIs are configurable in OAM and can be set to pretty much anything. By default, OAM will log a user out when they access any URI ending in logout.* where * is anything other than gif or jpg.

Session Synchronization
For applications that can be accessed from external/uncontrolled networks, especially public extranet applications, it is a good idea to put measures in place to make sure that the user associated with an active OAM session is the same as the user associated with an active container/application session being protected by OAM.

What you are trying to avoid is a situation where users either intentionally or accidentally log in to OAM as themselves but access the application as someone else.
The basic idea is to have a filter in place that compares the user in the OAM session to the user in the application/container session. Fusion Middleware 11g contains such a filter called the SSO Synchronization Filter. You can read more about it here: http://download.oracle.com/docs/cd/E15523_01/core.1111/e10043/osso.htm#CHDHDBED

Session Cookie Overriding
Finally, if OAM is protecting multiple containers or applications that by default issue session cookies with the same name then it is important to realize that as a user moves from one container/application to another that the session cookie of the 2nd container/application will blow away the session cookie from the first container/application.

An example of this is OAM protecting multiple WebLogic applications that are not sharing a session. The JSESSIONID cookie issued when a user accesses a second application will blow away the JSESSIONID from the first application.

Now, what you usually see in such a setup is that the user can go back and access the first application without having to login again. However, underneath the covers they will be issued a new session. So, upon returning to the first application, any data associated with their original session will be lost and the application flow may be disrupted or different from the expected behavior.

Sunday, March 21, 2010

Oracle Service Bus and Kerberos

This topic has come up in a number of discussions at a number of customers in the past few weeks. The basic question is "How does OSB work with Kerberos (WCF) clients?". The short answer is "The simplest thing to do is just use OSB as a pass-through." I've given this answer a few times, and people seem disappointed. I think they expect that there is "more". I wanted to use this post to help people understand some of the details of OSB and Kerberos that make this the most sensible approach.

Friday, March 19, 2010

Speeding up your OES-enabled app

When you secure a WebLogic app with OES or use OES to secure a Java based application using the Java Security Module the overhead and performance impact is minimal (it's usually measured in microseconds). In fact most customers report that OES is faster than the code it replaced.

When you use OES' Web Services Security Module your application makes SOAP or RMI calls over the network to a central server or cluster of servers. This is inherently slower than in process calls, not because the Web Service SM is slow, but because SOAP, XML, and SSL all add computational overhead, and network communication adds latency. Consider that a simple ICMP ping is measured in milliseconds and it's clear that this might be a fairly large impact on your application.

When an application calls OES there is a single, common Java API you can use regardless of which SM you are using. At its simplest the API takes three parameters - action, resource and context data - and returns a boolean along with context data. Programmers new to OES will often go no further than making calls to this API and if you are using the Java Security Module, which runs in the same process space as your application logic, you need go no further.

But if your making SOAP or RMI calls you'd be doing yourself a disservice by not looking further.

OES offers two additional API calls that allow you to make bulk authorization calls. One (isBulkAcessAllowed / isBulkAccessAllowed) allows you to send a batch of action/resource and context calls and get a list of true/false responses. The other (isChildResourceAccessAllowed / isChildResourceAccessAllowed) allows you to ask OES for a list of resources it knows about that the user is authorized to access.

These interfaces are also available in the WSDL and the .NET example shows how you can make these calls from C#.