Managing roles in an application with Redback is governed through an implementation of the Role Manager, an interface defined in the redback-rbac-role-manager artifact that encapsulates most of the most comment role related activities. User assignment of roles, creating and removing of roles based on templates (more on this later), and simple role existence activities.
Roles are loaded by the Default implementation of the role manager from a series of resources that are discovered in your classpath. The root of these files is searched for as:
META-INF/redback/redback-core.xml
This allows to you establish a basic set of resources, operations, roles and role templates that all other referencing applications can extend from. Other files that are loaded are located as:
META-INF/redback/redback.xml
Each of these files follows the same model, the one specified by point to xsd generated by modello.
<redback-role-model> <resources> <resource> <id>cornflakes</id> <name>cornflakes</name> <permanent>true</permanent> <description>my breakfast cereal</description> </resource> </resources> <operations> <operation> <id>eat</id> <name>Eat</name> <description>eat something</description> </operation> </operations> <roles> <role> <id>can-eat-cornflakes</id> <name>Role for happy cornflake eaters</name> <permissions> <permission> <id>eat-cornflakes-permission</id> <operation>eat</operation> <resource>cornflakes</resource> </permission> </permissions> </role> </roles> <templates> <template> <id>eater-template</id> <namePrefix>Eater of</namePrefix> <permissions> <permission> <id>eat-cornflakes-permission</id> <operation>eat</operation> <resource>${resource}</resource> </permission> </permissions> </template> </templates> </redback-role-model>
Resources are the entities in role based access control that roles provide access to through the binding of the resource with an operation in the form of a permission. In the example above, 'cornflakes' are the resource that are in play.
Operations are conceptually actions that can be performed, somewhat akin to verbs in the english language. 'Eat' in the example above is and action that can be performed on any given resource.
Roles are assignable entities that grant permissions to their assignies. In this example, a user that has the can-eat-cornflakes role assigned can...eat cornflakes.
Permissions are the component of a role and role template that bind an operation and a resource together into a form that is useful for authorization. In this simple example we have the 'eat' operation being paired with the 'cornflake' resource which effectively allows assignees to eat thier cornflakes.
Templates address the fundamental issue in role based access control systems regarding resources that may not exist at the time of role specification. For example it would be virtually impossible to specific all manner of possible foods you might encounter in life at application creation. The 'eater-template' above addresses this. If you are exposed to 'tirimisu', that would be created as a resource at runtime and then the eater-template would be run with the tirimisu as its target resource (note the ${resource})
Roles and Role templates would be woefully boring and tedious to work with if there was not some concept of inheritence. Inhertiance is also added through the model above.
META-INF/redback/redback-core.xml <redback-role-model> <resources> <resource> <id>cornflakes</id> <name>cornflakes</name> <permanent>true</permanent> <description>my breakfast cereal</description> </resource> <resource> <id>milk</id> <name>milk</name> <permanent>true</permanent> <description>white stuff from cows</description> </resource> </resources> <operations> <operation> <id>eat</id> <name>Eat</name> <description>eat something</description> </operation> <operation> <id>drink</id> <name>Drink</name> <description>drink something</description> </operation> </operations> <roles> <role> <id>can-eat-cornflakes</id> <name>Role for happy cornflake eaters</name> <permissions> <permission> <id>eat-cornflakes-permission</id> <operation>eat</operation> <resource>cornflakes</resource> </permission> </permissions> </role> <role> <id>can-drink-milk</id> <name>Role for milk drinkers</name> <permissions> <permission> <id>drink-milk-permission</id> <operation>drink</operation> <resource>milk</resource> </permission> </permissions> </role> <role> <id>bowl-drinker</id> <name>Bowl Drinker</name> <chlldRoles> <childRole>can-eat-cornflakes</childRole> <childRole>can-drink-milk</childRole> </childRoles> </role> </roles> <templates> <template> <id>eater-template</id> <namePrefix>Eater of</namePrefix> <permissions> <permission> <id>eat-cornflakes-permission</id> <operation>eat</operation> <resource>${resource}</resource> </permission> </permissions> <childRoles> <childRole>can-drink-milk</childRole> </childRoles> </template> </templates> </redback-role-model>
With this example we have added another resource and operation, which can be combined to allow a user to drink milk. We also added a new role called 'bowl-drinker' which has no additional permissions but illustrates the childRole concept, that someone with this role effectively has the two child roles, which when combined would all someone to eat their cornflakes in the morning, and then drink the milk.
Also added to this example is the can-drink-milk role to the eater-template, which would allow the user to automatically drink milk during any meal that might be created during runtime.
Since roles can be loaded up from different redback.xml files, it is possible to reference roles in the redback-core.xml file and have them add a child relationship to your role, and example of this is in play with continuum and archiva both. Each of these applications define an extension of the System Administrator role that is created in the redback-xwork-integration artifact (where is the redback-core.xml is). These extensions would simply add:
<role> .... <parentRoles> <parentRole>system-administrator</parentRole> </parentRoles> </role>
Then at role creation the role manager would know to have the System Administrator role create a child role relationship with the corresponding child role.
Templates can also have child and parent relationships that are all established during runtime.
NOTE: Roles can not declare childTemplate or parentTemplate relationships since roles are created at startup time. One way around this restriction is to add an aggregator role.
One very useful role pattern to keep track off is an aggregator role. In this case you would have the following example:
META-INF/redback/redback-core.xml <redback-role-model> ... <roles> ... <role> <id>eater-aggreator</id> <name>Eat Lots Role</name> </role> </roles> <templates> <template> <id>eater-template</id> <namePrefix>Eater of</namePrefix> <permissions> <permission> <id>eat-cornflakes-permission</id> <operation>eat</operation> <resource>${resource}</resource> </permission> </permissions> <parentRole> <parentRole>eater-aggregator</parentRole> </parentRole> </template> </templates> </redback-role-model>
In this example you can see that there is a role that is created at startup time called the eater-aggregator. Initially this role has nothing in it, no permissions, no child roles, nothing, its is totally empty. You can assign this role to someone and they get no added permissions. However, as new roles are created using the eater-template, anyone that has that eater-aggregator role assigned will automatically pick up permissions for each of these new roles.