In this post I’ll cover the OAM 11g concept of resources. The documentation does a reasonably thorough job of covering resources. Again though, in the interest of cutting through the clutter, I’ve compiled a list what I think are the most important points in understanding resources and OAM 11g:
- A resource is composed of a host identifier + URI expression. When a user makes a request it is normalized by OAM into an internal representation of the request consisting of a host identifier and URI; the query string is discarded. This internal representation of the request is then compared to the host ID + URL patterns of the resources you have defined. If there is a match then policies will be evaluated based on that resource.
- OAM 11g does not consider the query string when trying to match a request up to a resource
- If a request fails to match up with any of the defined resources then a failure is returned by the OAM server. With 11g webgates this always means that the request will be blocked. With 10g webgates the behavior is controlled by the “denyOnNotProtected” setting. If set to true then the request will be blocked. If set to false, then anonymous access will be granted and the request will be let through the webgate.
- A request will be matched to one and only one OAM resource.
- The algorithm used to decide what resource the request will be matched to in the event that more than one URL pattern match the URL in the request is a "best match" algorithm. We’ll go into more detail on this later in the post.
- A resource can be in no more than one authentication policy and no more than one authorization policy.
As I mentioned earlier, I think the OAM documentation on resources does a pretty good job but let me expand on it a little bit and try to clarify a few things.
A resource is composed of three parts: the resource type (this posts only covers HTTP type resources), a host identifier, and a resource URL. The resource URL mirrors the URI portion of the request URL which is the part of the URL after the server name (including the / following the server name) and before the query string (the query string is the ?). I wish they had named this the resource URI but what can you do. The resource URL can contain two special character sequences with special meaning ‘…’ and ‘*’. We’ll cover these special characters in a bit.
When you create a resource you do so within an Application Domain. That resource can then become a part of one authentication and one authorization policy inside that Application Domain. Even though this resource is scoped to an Application Domain, you cannot define the same resource (host identifier + resource URL) in another Application Domain.
Now we’ll finally get to the special characters ‘…’ and ‘*’. * (asterisk) can only be used in the last level of the “path” and by this we mean after the final / in the URI. It can be used in two ways: as the last character in the resource URL or preceding a file extension (.jsp, .html, .gif etc).
The * (Asterisk)
When * is used as the last character in the resource URL it matches any string of 0 or more characters that does not contain a ‘/’ (slash). In other words * when used in this way matches any resource that does not go another level deep.
For example, the resource /foo/* will match /foo/index.html and /foo/helloworld but not /foo/bar/hello.jsp.
The other use of the * is preceding a file extension. Let’s say you want to make all the images in a particular webapp open to anonymous access so that they can be linked to from other apps without requiring authentication to OAM. Just create a /app/*.gif resource and throw it into public authentication and authorization policies.
The … (Ellipsis)
The three periods (called an ellipsis) matches any sequence of one or more characters that starts and ends with the forward slash character ‘/’. It is used for creating resource objects that cover multiple “directory” or “realm” levels. The ellipsis can be used only once in a resource URL.
Now the documentation says that the ellipsis matches any sequence of one or more characters that starts and ends with the forward slash but my observation is that it also matches a single forward slash. So, /…/ will match ‘/’. ‘/index.html’, and ‘/foo/bar/help.jsp’
Most of the time you will be adding an asterisk together will the ellipsis. To create resources that match every request under a given context root (directory).
So, let’s say you have an application that handles procurement for your company that is deployed under the context root /procurement. You might create a resource /procurement/…/* that will match all requests under ‘/procurement/’.
So, let’s say you have multiple resources that might match a given request. An example of this would be having ‘/…/*’, ‘/somedir/*’, and ‘/somedir/*.jsp’ defined as resources and having request scome in for ‘/somedir/index.html’ and ‘/somedir/hello.jsp’.
OAM uses a “best fit” algorithm to determine which resource the request will be matched with; which is to say, it will pick the resource that contains the most amount of specific characters that match the URI of the request or put another way, the resource that has the least amount of characters in the request matching a wild card expression in the resource.
In our example /somedir/index.html will match with ‘/somedir/*’ and /somedir/hello.jsp will match with ‘/somedir/*.jsp’.
If this confuses you or if you are debugging a policy where you think the request is matching a resource different from the one you expect you can see what resource a request was matched with in 2 ways:
- Look at the logs. Filter at the notification level for the word “protected”. Look for the “Called isResourceProtected ()” message that contains the request you want to examine. Then look for the next “Returning from isResourceProtected()” message which contains the resource your request was matched with.
- You can configure a response that will create a header containing the resource (host ID and resource URL) your request was matched with. You can then examine this header in your application code. We’ll talk more about responses in a future post but the value for this response is $request.policy_res