Tuesday, May 25, 2010

When NOT to use OES' bulk calls

The simplest OES API is the one that allows you to ask "is this user authorized to do X?" Also known as isAccessAllowed. As I mentioned back in March OES also has a couple of calls that allow you to speed things up by making bulk 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 methods are great and can really improve your apps performance if you use them when appropriate. I've had to try to talk more than a few people out of using the them when they weren't necessary or proper and I thought I'd write down the reasoning for anyone else that needs it. Sometimes the most difficult and important part of having a particular tool in your toolbox is to know when to avoid its use.

First things first:
When you create resources in OES you're basically creating a hierarchy not unlike that of a filesystem. The end result is a tree and you can write policies on any node in the tree.

When you ask "isAccessAllowed" with a single resource you're asking about a particular node in that tree.

isChildResourceAccessAllowed
Let's talk about when not to use isChildResourceAccessAllowed first because it's the more obvious one.

Let's say I create a resource tree of the following resources:
  • /accounts
  • /accounts/checking
  • /accounts/savings
  • /accounts/investing
I'd mark checking, savings and investing as "virtual" which means that you can ask OES about anything that starts with those strings and it will evaluate the policies on the higher level object.

I'd probably write policies on checking and savings accounts that say to "you're allowed to withdraw money if you are the account owner". Then at runtime if I asked OES can "Chris" withdraw "$1,000,000" from /accounts/checking/234877682345 OES can answer that question quite easily - it just has to figure out if "Chris" owns that account and then it can say yes or no. It's then up to the banking app to decide if there's enough money in the account (though there never is).

Unless I actually went in and created every single checking account at the bank under /accounts/checking the isChildAccessAllowed() method can't work - OES doesn't know how to get a list of the checking accounts! (at least not in this example!)

Another case where it's inappropriate is when OES knows about lots of resources but you only really care about a few of them. For example if you had /myapp/feature1 through /myapp/feature1000 and you're trying to decide whether to show numbers one through five. You'd ask OES for all child resources and it would have to evaluate the policies for 1000 objects before you'd hear back about the five you actually cared about. So a big fat waste of OES' and your user's time.

So when should you use isChildAccessAllowed? When OES has a list of resources and you want to know about all of them that the user can see. Things like menu options or drawers on the Pill O-Matix make sense.

isBulkAccessAllowed
What about the other one - isBulkAccessAllowed()?

The isBulkAccessAllowed() method is simply a batch version of the original, simple isAccessAllowed call. If you have 100 resources in your application and you want to find out which the user is allowed to access you might call isBulkAccessAllowed. Seems perfectly logical, and it is. There's only one tiny nuance though: sometimes it's more trouble than its worth.

When you have a list of resources you can iterate over it and ask OES about each resource literally as you iterate over them. One time through and bing, bang, boom, your done. No muss, no fuss.

When you make the bulk call to OES you have to make the list of resources, call isBulkAccessAllowed() and then parse the result - meaning iterating over the resources again seeing if the resource is in the list of resources the call returned. Frankly a bit of a pain in the rump.

If you're making calls to a remote SM over Java or RMI you're saving the round trip time of talking to your PDP times the number of resources. But if you are using an embedded SM (e.g. the Java or WebLogic SM) then you've gained nothing and only caused yourself more grief.

So if you're using the embedded SM and might switch to a centralized SM in the future then by all means use the isBulkAccessAllowed() call. If on the other hand you know for a fact that you will always be using an embedded SM I generally say skip using the isBulkAccessAllowed() method.

Hope this helps someone out there!

2 comments:

  1. Hello, Currently working our way through learning curve with OES and this comment caught my attention because we would like to leverage OES to return a list of available resources from an authenticated policy. "OES doesn't know how to get a list of the checking accounts! (at least not in this example!)"

    Do you have examples returning a list of authorized resources. In our most complicated case we're looking to return 1000's of selectable items based on runtime constraints. I keep coming back to rules associated to roles where the rules define the literal constraint logic, for example column contains these value [value_x, value_y, value_z]. Would seem we could use an attribute retriever to fetch rules maybe as PIP?

    Thanks.

    ReplyDelete
  2. The problem is that unless you go and create all of the resources inside OES there's no way for OES to tell you that the user can see them.

    Take my example above. Let's say I want to withdraw $20 from an account. Which accounts should I be allowed to withdraw that money from? If you tell OES about all of the accounts like so...

    /accounts/checking
    /accounts/checking/1
    /accounts/checking/2
    /accounts/checking/3
    /accounts/checking/4
    /accounts/checking/5
    /accounts/checking/6
    /accounts/checking/7
    ...
    accounts/checking/234877682345

    if I do THAT then I can have OES give me a list of all of the accounts Chris can withdraw from.

    What's more is that every time you added a new account under accounts/checking you'd need to do a Policy Distribution to all of the Security Modules so that THEY know about the resource.

    So yeah, you *could* do that, but it's really not scalable.

    If you have a fixed number of resources (e.g. menu options) that don't change all that often then it works great.

    ReplyDelete

Note: Only a member of this blog may post a comment.