The security file defines permissions to control access to Domain data on the basis of user names and roles existing in the server. When creating or running a report based on a Domain, the user name and roles are checked against the permissions in the security file. Permissions can be set separately on the data’s columns and rows.
Security on columns is defined by permissions on the sets and items of the Domain, corresponding to columns in the data source. For example, only certain users might be able to see sensitive employee information such as a Social Security Number. Security on rows is defined by permissions on the data values, for example a manager might only be allowed to see the salary column of employees whose manager field equals the manager’s employee number.
The IDs of tables, columns, sets and items that appear in the design are referenced by the security file. In Domains, columns display the items in the Domain; rows display the values of each item. Column security is defined on itemGroupId and itemId; row security is defined on resourceId.
A user can only see results where he has both column- and row-level access. For instance, in a certain Domain, user David has access to columns A-F and rows 1-6. Tomas has access to columns B-C and rows 1-3. Anita has access to columns C-E and rows 2-5. When the users run reports from the Domain, they get different results. David sees data in cells where columns A-F and rows 1-6 intersect. Tomas sees data only where columns B-C and rows 1-3 intersect. Anita sees data only where columns C-E and rows 2-5 intersect.
|
Item A |
Item B |
Item C |
Item D |
Item E |
Item F |
1 |
David |
David Tomas |
David Tomas |
David |
David |
David |
2 |
David |
David Tomas |
David Tomas Anita |
David |
David |
David |
3 |
David |
David Tomas |
David Tomas Anita |
David Anita |
David Anita |
David |
4 |
David |
David |
David Anita |
David Anita |
David Anita |
David |
5 |
David |
David |
David Anita |
David Anita |
David Anita |
David
|
6 |
David |
David |
David |
David |
David |
David |
For a given query on the data source, the security definition finds the access grants and determines his access rights, determined first for item groups and items, then for resources. When the query is passed to the data source and the report is run, the grants are applied as filters on the report’s columns and rows. Security that is defined on the physical layer applies to all content in the presentation layer. Security that is defined on a join applies only to the presentation layer content that is specific to the join.
When a user is designing a report in the Ad Hoc Editor, he sees only the columns to which he has access. When the report runs, portions to which the user has no access are blank.
Access grants take a principalExpression that evaluates the principal in authentication objects created in the Acegi security framework (http://community.jaspersoft.com/). The standard expression is
<principalExpression>authentication.getPrincipal().getRoles().any{ it.getRoleName() in ['ANY_SUPPORTED_ROLE'] }
</principalExpression>
The expression gets the current authentication object and determines the access privileges of the principal in the object. Then, from the server, it gets the user and roles associated with the object. Finally, it evaluates the roles for the specified role. The access grants are applied to the role.
The expression evaluates to
<principalExpression>authentication.principal.roles.roleName in ('ANY_SUPPORTED_ROLE')
</principalExpression>
While the standard principal expression tests for a given role, an expression can test for any object in the principal. For example, this expression tests for attribute A:
<principalExpression>authentication.getPrincipal().getAttributes().any{ it.getAttributeA() in ['ANY_SUPPORTED_ROLE'] }
</principalExpression>
The scripting language for principalExpression is Groovy.
|
For more information about Groovy, go to http://groovy.codehaus.org. |
All access grants for a Domain are defined in a single security file that is attached to the Domain as a resource, as described in Security and Locale Information for a Domain. The default access is granted.
When creating a security file, be sure to use the IDs of items and groups as they are defined in the Domain design file exported from the Domain Designer. For more information, see Working With a Design File.
If you modify the Domain, you should also export the design file and update the security file with any IDs that have changed. Update the security file using the Change function on the Edit Domain page of the Domain Designer.
|
Changing a Security File in the Domain Designer |
A typical security file has the following structure:
</resourceAccessGrants> </resourceAccessGrantList> ... </resourceAccessGrants> <securityDefinition xmlns="http://www.jaspersoft.com/2007/SL/XMLSchema" version="1.0" itemGroupDefaultAccess="granted"> <resourceAccessGrants> <!-- Begin row-level security --> <resourceAccessGrantList id="expense_join_resource_access_grant" label="aLabel" resourceId="expense_join"> <resourceAccessGrants> <resourceAccessGrant id="expense_join_ROLE_SUPERMART_MANAGER_store_row_grant"> <principalExpression> authentication.getPrincipal().getRoles().any{ it.getRoleName() in ['ROLE_SUPERMART_MANAGER'] } </principalExpression> |
<filterExpression>s.store_country in ('USA') and s.store_state in ('CA') </filterExpression> </resourceAccessGrant> ... <itemGroupAccessGrants> <!-- Begin column-level security --> <itemGroupAccessGrantList id="expense_join_item_group_access_grant_group" label="aLabel" itemGroupId="expense_join" defaultAccess="denied"> <itemGroupAccessGrants> <itemGroupAccessGrant id="expense_join_super_user_item_group_grant" access="granted"> <principalExpression> authentication.getPrincipal().getRoles().any{ it.getRoleName() in ['ROLE_ADMINISTRATOR'] } </principalExpression> </itemGroupAccessGrant> ... </itemGroupAccessGrants> </itemGroupAccessGrantList> ... </itemGroupAccessGrants> </securityDefinition> |