Jump to content
Changes to the Jaspersoft community edition download ×
  • This documentation is an older version of JasperReports Server Security Guide. View the latest documentation.

    Creating a Domain Security File

    A Domain’s security file contains item and resource access grants that specify access based on certain aspects of a user, such as attributes or roles. Typically, access grants check a user’s roles or attributes and grant access to the columns and rows available to the user.

    A Domain’s security file has two types of access definitions:

    Row-level access determines which rows in the data source can be displayed to a specific user.
    Column-level access determines which columns in the data source can be displayed to a specific user.

    This section describes the access grant syntax and illustrates both kinds of access grant.

    note-icon-ns_28x28.png.bb506063368311c5c54877be8cad4315.png

    Note the comments in the XML examples in this section; for example: <!-- Comment -->. It’s good practice to comment the access grants you define, and to format your XML neatly. We recommend using an XML editor when creating security files. See Domain and Security Recommendations.

    Access Grant Syntax

    All access grants take a principalExpression that gets the user's attributes or roles and evaluates them. Some access grants also take a filterExpression that additionally filters information based on the attributes or roles found by the principalExpression.

    You can use the following services to get attributes or roles in a principalExpression:

    attributesService – Use to retrieve or test for attributes you have defined at the user, organization, or tenant level. Does not support roles.
    authentication.getPrincipal() – Use to test for roles. Does not support hierarchical attributes.

    You can use the following services in a filterExpression:

    attributesService – Use to filter attributes when you have attributesService in the principal expression. Does not support roles.
    testProfileAttribute – Use to filter attributes from the principal expression. Supports either attributesService or authentication.getPrincipal() in the principal expression.

    attributesService

    attributesService retrieves hierarchical attributes for a user. A user can inherit attributes from their organization or the server in addition to any attributes assigned to the user directly. When providing an attribute, you can either specify the category (user, tenant (organization), or server) in which the server should look for its value, or allow the server to locate the value hierarchically.

    attributesService.getAttribute('AttrName',Level[, condition]))

    getAttribute() takes the following arguments:

    AttrName – String that specifies the attribute to check. Can be any customer-defined attribute, such as Cities.
    Level – Category that specifies the level in the hierarchy to check for attributes. One of: null, 'SERVER', 'TENANT', or 'USER'. To use all available attributes from all levels, use null.
    required (optional) – Boolean that specifies whether or not the attribute is required.
         When set to true, an error message is displayed in the UI if the attribute is not present.
         When set to false (default), if the attribute is not present, no error is thrown and the filterExpression is not performed. In this case, unfiltered information which the user is not explicitly authorized to view is displayed.

    note-icon-ns.png.2dc5d5c447bce8448259a415729b9ba7.png

    attributesService is implemented in Groovy. For more information about Groovy, see www.groovy-lang.org.

    For example, the following expression tests whether the user has AttrValue set for the AttrName attribute anywhere in the hierarchy.

    <principalExpression>  attributesService.getAttribute('AttrName',null,true)?.getAttrValue().equals('AttrValue')</principalExpression>[/code]                        

    authentication.getPrincipal()

    To retrieve information about roles, you must access Spring's currently authenticated principal object. You do this using authentication.getPrincipal(). For example, the following principal expression checks whether the user has the ROLE_ADMINISTRATOR or ROLE_SALES_MANAGER role.

    <principalExpression>  authentication.getPrincipal().getRoles().any{ it.getRoleName()     in ['ROLE_ADMINISTRATOR','ROLE_SALES_MANAGER'] }</principalExpression>[/code]                    

    The testProfileAttribute Function

    You can use testProfileAttribute in a filter expression. It is supported when the principal expression uses either attributesService or authentication.getPrincipal.

    The testProfileAttribute function takes two parameters:

    testProfileAttribute(table_ID.field_name, 'attribute')

    where:

    table_ID.field_name is the table name and field name of a field whose value you’re comparing to a user attribute.
    attribute is the name of the user attribute.

    note-icon-ns.png.3ebc8b5ac02a9274a90e130d368c3b7c.png

    In JasperReports Server 6.0, we added support for hierarchical attributes, which extend attribute functionality. You can add attributes to a principal expression or filter expression as described in Updating your Security File.

    Filter expression using testProfileAttribute

    <filterExpression>testProfileAttribute(store1.store_country,'country')</filterExpression>

    Using attributesService in a Filter Expression

    You can also use attributesService in a filter expression, but only when you have attributesService in the principal expression. The following filter expression gives the same results as the filter expression in “Filter expression using testProfileAttribute”

    Filter expression using attributesService

    <filterExpression>  store1.store_country ==(groovy('attributesService.getAttribute("country", null).attrValue'))</filterExpression>[/code]                    

    Row-level Security

    This section gives an overview of row-level security and then shows how CZS uses row-level security to restrict access based on Cities and ProductDepartment.

    Understanding Row-level security

    Row-level access determines which rows in the data source can be displayed to a specific user.

    For example, consider a table that includes values for the cities where products are sold. You could define a resource access grant that finds users for which a city has been defined as a profile attribute and, for each such user, limits access to rows where the city value is the user’s specific city.

    For example, take Rita and Alexi. Both have the same role and the same access to the Sales Numbers analysis view, but CZS doesn’t want them to see the same data—Rita should see data about San Francisco, Sacramento, and Los Angeles; and Alexi should see data about Osaka and Sakai. Without attributes, this would be possible only if CZS’s access roles were defined along geographic lines.

    note-icon-ns_28x28.png.57a31d1c3fcd9064c59820448bd231ce.png

    Each access grant ID must be unique within the scope of the security file.

    You can define several similar resource access grants for each resource defined in your Domain. By default, the server assumes access grants are combined with a logical AND. You can force the server to use a logical OR by setting the orMultipleExpressions property to TRUE.

    To implement row security, CZS uses attributesService to check for the

    For example, CZS used the following XML to define a principal expression and filter expression that grant access to users based on their Cities profile attribute:

    The principal expression gets the values of the Cities attribute for the logged-in user. Since attributesService supports hierarchical attributes, CZS set the null parameter to indicate that they want to look at the values from all levels. The optional true parameter ensures that if a user without any values for the Cities attribute accesses the view, they will receive an error.

    The filter expression checks the user’s Cities profile attribute as well, but it compares this value with the values in the Domain’s store_city field. The Domain then returns all the rows that match the user’s Cities profile attribute.

    CZS’s Resource Access Grants

    CZS uses the access grant above to determine data access based on a user’s Cities profile attribute. Because CZS defines all their attributes in the same manner, they can use a similar resource access grant to determine data access for users based on their ProductDepartment profile attribute.

    The resulting security file included these two resource access grants (see the complete file in Domain Security File).

      <!-- Row level security -->    <!-- What access do roles/users have to the rows in the resource? -->  <resourceAccessGrantList id="JoinTree_1_List" label="ListLabel"    resourceId="JoinTree_1">    <resourceAccessGrants>          <!-- Row level for Cities -->      <resourceAccessGrant id="Jointree_1_row_access_grant_20">        <principalExpression>attributesService.getAttribute('Cities', null, true) != null           </principalExpression>        <filterExpression>testProfileAttribute(store.store_city,'Cities')        </filterExpression>      </resourceAccessGrant>      <!-- Row level for Product Dept -->      <resourceAccessGrant id="Jointree_1_row_access_grant_30">         <principalExpression>          attributesService.getAttribute('ProductDepartment', null, true) != null        </principalExpression>        <filterExpression>testProfileAttribute(product_class.product_department,          'ProductDepartment')</filterExpression>      </resourceAccessGrant>     </resourceAccessGrants>      </resourceAccessGrantList>[/code]                    

    Column-level Security

    Column-level access determines which columns in the data source can be displayed to specific users.

    Understanding Column-level Security

    Consider a table that includes employee contact and salary information. You could define item group access grants that check the user’s role and grant access to the salary field only if the user has the Human Resources role. For example, the following code sample modifies access for the ROLE_SALESREP role, first by revoking the default access for that role and then granting access to sales information only. The principle expression determines which users the item group access grant applies to (users with the ROLE_SALES_REP role). The item access grants determine the specific access of the users. All role-specific access is revoked then access to the StoreSales and StoreCost item is granted:

    CZS’s Item Group Access Grants for Sales Data

    To ensure that sales representatives don’t have access to cost information, CZS adds item group access grants; the first grants full access to managers and the administrator:

    CZS then adds an item group access grant that grants limited access to sales representatives; the following XML grants access to the Store Sales and Sales Units fields while revoking access to the Store Cost field:

    Uploading the Security File

    CZS uploads the security file each time they add a new access grant. You can upload the security file when you add or edit a Domain. Make sure to click Submit after you have successfully uploaded the security file.

    js-czs-security-upload_748x359.png.46790ef3758bb595021b5413a5a6b67a.png

    Uploaded Security File in the Domain Dialog


    User Feedback

    Recommended Comments

    There are no comments to display.



    Guest
    This is now closed for further comments

×
×
  • Create New...