Application Security, Part 29
It's high time I finished this series . . .
Okay, so obviously the idea with the Authorization Manager API is that when a button is clicked or a menu option is selected, one could have a call to AccessCheck to determine if that operation is allowed for the current user. But we have a problem, and it’s actually quite a challenging one: in Authorization Manager, we have operations, and on our user interface, we have menu options and buttons, and the problem is how to map the operations to the controls. Let me put it this way: how does a button or a menu option know what operation it corresponds to? The button or menu option has to know its corresponding operation in order to call AccessCheck to determine whether the current user is allowed to use the button or menu option.
One solution to this problem that may spring to mind is to use the Tag property of the controls to store the numbers of the operations corresponding to them. Then, to check for authorization for the user to use it, a control merely has to call the AccessCheck method, passing in the value of its Tag property as the operation number, and AccessCheck will determine if the operation number identified by the value of the Tag property is authorized for the current user. A problem with this solution is that precisely the sort of controls for which one would want to authorize use, namely menu items, do not have Tag properties.
Well, then, what about having the names of the operations defined in the Authorization Manager store correspond exactly with the names of the controls? Then, based on the name of the control, one could search for the corresponding operation by name, and pass its number to the AccessCheck method to verify authorization. That solution is also no good, however, once again because the controls that we most often want to restrict access to, menu items and toolbar buttons, have no access to their own names.
What would work would be to create a subclass all of the classes of controls for which one would want to authorize permission—customizing the controls, that is to say—adding an AuthorizableOperation property to the controls to store the number identifying the operation that corresponds to the control in Authorization Manager. Without a great deal of effort, though, which may turn out to be in vain in the case of menu items, the designer will no longer recognize the sub-classed controls. And while you could rebuild the controls as user controls, again, that would be extremely taxing in the case of menu items. In general, I think that if you are finding yourself writing your controls in order to map operations in Authorization Manager to controls in your application, then Authorization Manager is proving to be far more hassle than it is worth.
So, how should we map the operations in Authorization Manager to the controls of our application? Well, the solution that I settled on was to create an XML schema to describe the controls of an application and associating each control with the number of an operation within Authorization Manager. The idea is this:
1. When an application executes, it will read an XML document that conforms to the schema, which will tell the application which operation number in Authorization manager corresponds to any given control within the application
2. Given that operation number, the application will be able to invoke the AccessCheck method of Authorization Manager to determine if the operation is permitted for the current user.
3. If the operation is not authorized for the current user, the application will hide the control, or, in cases where the control must still be shown, prohibit a certain use of the control.