Interesting. Although a bit sticky, I think.
I'm very much a proponent of "wrap-around" security myself, as you'll discover if you spend much time here. In this particular case, however, I don't know that there's enough of a distinction between business function and security to externally supply that kind of control. In other words, to restrict access to the UI element, you'd first need to know the business application of that particular UI element. So it's not really something that can be applied by a third party who knows nothing of the application.
Notice 2 things about the example I supplied:
1. The element render check is deferring to an external security manager of the "black box" variety. It provides a yes/no confirmation and volunteers nothing, as is consistent with good security practices.
2. I don't expect the client to be honest. So I also guard the function(s) that the UI element interacts with. This is critical
. In fact I recently received an application with Yet Another Do-It-Yourself Security System (YADIYSS) which depended on UI control hiding. By crafting a suitable request, not only can I invoke the "protected" function, I can modify data in the database. Not just mine, but other people's as well. In fact, depending on how sloppy the DBA was, I can potentially spike the entire OS.
So don't just consider security based on what the user can see. You don't always have to see a target to hit it.
As far as it goes, the most popular way to apply security externally is to use an AOP wrapping approach. You can for example, craft an annotation such as
And/or apply the same functionality from an external XML config file. The Spring Framework is good for this kind of stuff.
The Sun standard J2EE
container managed security system (which I favor) can guard URLs by patterns
defined in the web.xml file. It's a little trickier in JSF
than in most J2EE frameworks, but it can be done and I do it extensively. In fact, all my administrative functions are under the "admin" sub-context as far as their URLs go. That blocks attacks at the server level, before the app ever has to worry about it. The app never sees forbidden attempts at all.
I should point out that quite a few of my apps have more than one type of administrator. Sometimes there's a "sysop" role, a "diagnostic" role and an "application administrator" role. The application administrator typically invokes application controls and screens that configure the app and sometimes the non-admin users. One of my bigger apps also had an "auditor" role. That was very much like what you're talking about, where certain controls were omitted when an auditor looked at a page, because the auditor was permitted to review, but not to update data. However, I did still guard the update logic independently. As I said, hidden targets aren't safe.
Finally, in the event that I actually did have some sort of specialized control that could only be used for administrative purposes, I'd probably code the guards right into the control.
Incidentally, the Struts
HTML tags can be role-controlled. JSF tags don't generally have that ability, excepting some of the MyFaces Tomahawk elements. I'm not sure why. Maybe they figured that EL was sufficient.