Reading through the faq's on security as well as documentation on different forms of security, I have not seen any references to complex authorization pre-checks. I was hoping to get some insight, as I am not an expert in this area and may have missed the reference.
We have implemented service based security, meaning the restraints on authorization are placed on specific services and or domain objects in the application. Authorization checks work well and are much the same security implemented in JAAS/JBoss. The problem is actually in determining whether a principal has permissions to a resource prior to the actual call being made.
As a scenario:
A domain object Person. Our ACL would be something like Read Update Create Delete
From the UI perspective this is a pretty simple thing to do. In JSF/Seam we can dynamically enable/disable the update button based on the ACL of Person given the Principal. If we add another domain object, say Location, and it also has an ACL then permission checks would be based on both the ACL of Person and Location. That is assuming that a single button would result in the operation on both domain objects. As you can see, adding services that make use of domain objects and/or other services, can become quite complicated. In addition, any links to this page would not be enabled if the principal did not pass at least one of the authorization checks for all of the actions that could be performed on that page. The thought is that there is no reason to present a link to the page, when the user cannot even read a Person or Location.
We are now in the beginning stage of migrating our application to a component based architecture using Seam and JSF. This will entail creating reusable components that would encapsulate the security pre-checks. So the problem is defining what domain objects a component is directly making use of as well as what other components that are directly being made use of. Following the definition chain to each domain object and nested component, we can derive a concrete list of domain objects to check for permissions.
I first thought that I would create an annotation that would define what secured operations that the method performed. The code could then be scanned at start up to determine the list of domain objects that should be checked given a starting definition and following the chain to other definitions, then ending at a domain object that authorization could be performed on. The problem with this solution is the definition of what operations are being performed.
In a purely fictitious example we have a screen that makes use of a component to find a person by name. It would allow the input of an address and register the located person with that address. To access this screen the user should have permission to the Find Person service, create a Location and call the Register service.
The code may look something like this:
The problem with this approach is that any of these methods could be overridden, making the registration non-unique. In order to make this approach work each method that could be annotated would have to have a unique name. A name could be added to the annotation, but this seems to be getting to be too verbose and against the original intention, which is simplicity for developers and easy maintenance. An alternative would be to actually scan the call chain, in much the same way as a profiler, looking for paths that end in a secured operation. But, this could be too time consuming to do at startup.
This, finally, leads me to the reason for my post. I started wondering if I had missed some standard solution for this problem, or if someone might have some insight or advise. How does one predetermine permissions across a complex graph of components that make use of secured services or domain objects, without hard coding the service and domain object permission checks at the beginning of every call chain?
Most 'service' implementations are built on top of (or run under) something like a servlet container (tomcat) or a J2EE engine (JBoss). All of these have built in functions for access control. They typically use ACLs and can be driven by XML config files, or databases.
I'll recommend looking at how they do it, even if you don't plan to run under Tomcat. And since Tomcat is open source and well tested, I'd recommend you look carefully at using it.
I dislike annotations for uses such as you are describing, for many of the reasons you write, plus they are ugly. IMHO, etc.