Data Access Control (DAC) is an important aspect of any data oriented solution. One of Jello's key features is its inline Authorization Model. With Jello you can assign different access levels for data elements at any resolution (Namespaces, Entities, Fields, Actions) and specify who is authorized to access the data via the REST API.
You define an access control by adding @Accessible (or @Expose for data fields) annotation to a data element.
These annotations affect only the elements accessed via REST API while the Java access scope is determined, as usual, by the Java access modifiers (public
/protected
/private
).
By default, none of the data model elements is accessible via the REST API. In order to expose a data element you need to explicitly mark it as accessible. The @Accessible (or @Expose for data fields) annotation lets you specify which of the elements in your data model to expose.
Cascading access check: Whenever a REST request is trying to access a data element, Jello will start checking access, starting from the top of the model hierarchy. First the Namespace, then the Entity, and lastly the Fields and Actions. For example - in order to access a Field or an Action, The Entity must be marked as accessible and the Namespace must be accessible as well.
Packages are accessible by default.
Add @Accessible (jello.security.Accessible) annotation to the package info file to restrict access to entities under specific namespace via REST API.
Example:
1 2 3 4 5 | // File: demo/package-info.java @Accessible(Role.ADMIN) package demo; import jello.security.Accessible; |
Add @Accessible (jello.security.Accessible) annotation to an Entity class to mark the entity as a accessible via REST API.
Example:1 2 | @Accessible public class Product extends JelloEntity { |
Note: Entity class can be marked, at the same time, as private
for internal Java scope and as @Accessible
for external REST scope.
Add @Expose (jello.annotation.Expose) annotation to a data Field class to mark the field as a accessible via REST API.
Example:1 2 | @Expose private Double price; |
Note: Fields can be marked, at the same time, as private
for internal Java scope and as @Expose
for external REST scope.
Add @Accessible (jello.security.Accessible) annotation to a public
method to mark the method as an accessible Action via REST API.
1 2 | @Accessible public static List<Product> getProductsByRating(Integer rating) { |
Note: The @Accessible annotation has no effect on none public
methods. Jello annotation processor should issue an error upon such cases.
Specifies which Role is authorized to access the data.
Role | Syntax | Description |
---|---|---|
ALL [default] | jello.security.Role.ALL | Allow access for all users, both authenticated and unauthenticated (Guests). |
USER | jello.security.Role.USER | Allow access for authenticated users. |
ADMIN | jello.security.Role.ADMIN | Allow access to user logged-in as Administrator. |
SYSTEM | jello.security.Role.SYSTEM | Allow access for system calls such as Scheduled tasks and others |
OWNER | jello.security.Role.OWNER | Allow access to the user who created the Instance. Tests against the createdBy Audit field. |
Role Based Group | Role ID - String | Allow access to all users assigned to a specific role. See: Define Custom Roles |
Access By Action | Security.ByAction + method full path | Allow access by specific action |
Syntax:
@Accessible(role) | @Accessible({role1, ....}) | @Accessible( retrieve = role | {roles}, create = role | {roles}", update = role | {roles}, query = role | {roles}, delete = role | {roles} ) @Expose(role) | @Expose({role1, ....})
Examples:
1 | @Accessible(Role.ALL) // Default, Same as @Accessible with no parameters |
1 2 | @Expose({Role.OWNER, "ManagerRole"}) private Integer salary; |
1 2 | @Accessible({Role.ADMIN, Role.SYSTEM}) public static String createCatalog() { |
1 2 3 4 5 6 7 8 | @Accessible( retrieve = Role.ALL, create = "AppAdminRole", update = { Role.ADMIN, Role.OWNER, Security.ByAction + "app.partners.SendInvite" }, query = Role.USER, delete = { Role.ADMIN, Role.SYSTEM} ) public class Supplier extends JelloEntity { |
Note: When you set an Instance level access rule such as OWNER role,
Jello will add an implicit 'filter by user' to each select request to ensure all REST requests are always secured.
Most of the select methods available in the JAVA API execute 'secured' select query
unless suggested otherwise in the method name, e.g JelloModel.unsecureSelectWithParameters(...)
.
REST API Method | Description |
---|---|
Any [default] | Applies to any of the REST API Methods. |
Retrieve | Privilege to retrieve a single Entity's Instance. |
Query | Privilege to Query an Entity's data set. |
Create | Privilege to Create a single Entity's Instance. |
Update | Privilege to Update a single Entity's Instance. |
Delete | Privilege to Delete a single Entity's Instance.
To be able to Delete By Query, both Query and Delete privileges must be given. |
Examples:
1 2 | @Accessible(Role.ADMIN) public class Supplier extends JelloEntity { |
1 2 3 4 5 6 7 8 | @Accessible( retrieve = Role.ALL, create = Role.ADMIN, update = Role.ADMIN, query = Role.ALL, delete = Role.ADMIN ) public class Supplier extends JelloEntity { |
Jello provides two core entities under jello.security
to managed roles.
These entities are accessible only for the app administrator.
jello.security.Role - you can add custom roles by providing a unique role name identifier.
jello.security.UserRole - you can assign users to a custom role by adding a UserRole instance that specifies the user ID and the role name.
Jello provides a Userprofile
REST service that you can call from the client to get details on the logged in user. It returns a jello.services.UserProfile.Profile
object as shown below:
REST call:
GET /jello/data/jello.services/UserProfile/whoAmI()
Response in case of logged in user:
result: { user: "John@Doe.org", isAdmin: false, roles: [ "BusinessPartner", "ContentEditor" ], logoutLink: "/_ah/logout?continue=/" }
Response in case of guest user:
result: { isAdmin: false, roles: [ ], loginLink: "/_ah/login?continue=/" }
Was this page helpful? Let us know how we did:
Last updated March 12, 2019.