Skip to content

Security and User Roles

Application's user accounts can be mapped to roles using the API documented below. A Backendless backend contains some system roles and may include developer-defined roles. There several system roles available in all Backendless backends. These roles are automatically assigned to every user under various conditions. Each role can configured with global, container and asset permissions.

Core security roles are assigned based on user authentication status and whether the user logged in via "classic" backendless login or through a social network. These roles are:

Security Role
Assigned to user when an API request is made by:
NotAuthenticatedUser
...a user who is not logged in.
AuthenticatedUser
...a user who is logged in.
SocialUser
...a user who is logged in via a social network (Facebook, Twitter, Google)
FacebookUser
...a user who is logged in via Facebook
GooglePlusUser
...a user who is logged in via Google
TwitterUser
...a user who is logged in via Twitter

Additionally the following roles are automatically assigned by Backendless to an API request when a corresponding secret API key is used. By configuring access permissions to these roles an application may allow to custom server-side code (ServerCodeUser role), but completely reject access to the client apps (all other roles).

Security Role
Role is assigned when API uses secret key:
ASUser
ActionScript secret key
AndroidUser
Android secret key
DotNetUser
.NET secret key
IOSUser
iOS secret key
JSUser
JavaScript secret key
RestUser
REST secret key
ServerCodeUser
CodeRunner secret key

Backendless assigns multiple security roles for the same API request. For example, an API request made from a JavaScript application where user is not logged will have the following roles assigned: NotAuthenticatedUser and JSUser.

When an API call originates from business logic (Java, JS or Codeless), Backendless assigns the ServerCodeUser role.

Important

Business logic is the only exception to the rule for assigning NotAuthenticatedUser and AuthenticatedUser roles. When business logic makes an API call and there is no authenticated user in the context of the call, Backendless assigns only the ServerCodeUser role. Otherwise, if there is an authenticated user, then both ServerCodeUser and AuthenticatedUser roles are assigned to the request.

Adding Roles

A developer-defined role can be added using Backendless Console:

  1. Login to Console and select an application.
  2. Click the Users icon.
  3. Click the Security and Permissions section.
  4. Click the Add Role button and enter a name for the role.
  5. Click OK to save the role.

Role Permissions

A role may have multiple permissions assigned to it. A permission may either allow (GRANT) or reject (DENY) an API operation. Every operation which can be restricted with a permission has a subject. For example, the subject of a Data Service operation is a data record. For the File Service operations, the subject is a file.

All permissions are organized into a hierarchy: The global permissions apply to everything in the system. They either allow (GRANT) or reject (DENY) an API operation without distinguishing the subject. For example, a global permission may reject the Data Service's find operations for the users in the NotAuthenticatedRole. As a result, any not-authenticated user will not be able to retrieve an object from any data table in the application.

The asset container permissions inherit from the global ones and apply to a specific asset container, such as a data table. These permissions are scoped to a specific container type. For example, you may reject the get operation on file directory /privatefiles/for the users in role X. As a result, any user who belongs to the role X will not be able to retrieve files from that directory.

Finally, the asset permissions inherit from the ones for the corresponding asset container (if they are available) or from the global set. For example, an asset permission may reject access to a specific data object for one role and grant access to the same object for another role.

The diagram below illustrates the permissions inheritance ladder:

permission-inheritance

Once a role is assigned to a user account, any permissions assigned to the role (either granting or denying an API operation) automatically apply to the operations executed by the application on behalf of the user.

Retrieving Available User Roles

This operation returns a list of the roles associated with the user account currently logged in to the Backendless application. If the request is sent without logging in, the system will return only one role - NotAuthenticatedUser.

Non-Blocking API

The method call does not block - it returns immediately. The AsyncCallback arAssigning a Role to a Usergument receives either the response or the fault returned by the Backendless servers.

Backendless.UserService.getUserRoles( new AsyncCallback<List<String>>());

Blocking API

List<String> Backendless.UserService.getUserRoles() throws BackendlessException;

Example

Non-Blocking API

Before retrieving the user roles, log in as described in the Login section. Then, retrieve the user roles as follows:

//login user 
Backendless.UserService.login( "username@foo.com", 
                               "secretpassword", 
                               new AsyncCallback<BackendlessUser>() 
{ 
  @Override 
  public void handleResponse( BackendlessUser backendlessUser ) 
  { 
    // user has been logged in. Get user roles. 
    Backendless.UserService.getUserRoles( 
                                new AsyncCallback<List<String>>() 
    { 
      @Override 
      public void handleResponse( List<String> userRoles ) 
      { 
          //here we get all user roles - "userRoles". 
      } 

      @Override 
      public void handleFault( BackendlessFault backendlessFault ) 
      { 
         // get user roles, to get the error code call backendlessFault.getCode() 
      } 
    } ); 
  } 

  @Override 
  public void handleFault( BackendlessFault backendlessFault ) 
  { 
    // login failed, to get the error code call backendlessFault.getCode() 
  } 
} );

Blocking API

//login user 
Backendless.UserService.login("username@foo.com", "secretpassword");

// user has been logged in. Get user roles. 
List<String> roleNames = Backendless.UserService.getUserRoles();

Retrieving Users By Role

This operation works only with custom roles, otherwise an error message will be returned in response body. By invoking the getUsersByRole method, a client sends a request to the server which returns a response body with an array of users found by a specific role.

Non-Blocking API

public void findByRole( String roleName, boolean loadRoles, DataQueryBuilder queryBuilder, final AsyncCallback<List<BackendlessUser>> responder )

where

Argument                Description
roleName is a string name of a particular role.
loadRoles is an optional boolean parameter. When set to true, each user in a returned value will have a list of roles associated with that user account.
query an optional parameter that can be a plain object or an instance of Backendless.DataQueryBuilder. The returned list of users will satisfy the query.

Here is a detailed explanation of the parameters that can be used in the queryobject:

where

Argument                Description
pageSize sets the page size - which is the number of objects to return in the response. Maximum value is 100.
offset sets the offset - an index in the server-side storage from where the data objects should be retrieved.
properties sets the names of the properties which values must be retrieved from the server.
excludeProps column names that should be excluded from a query.
where sets a search query. A query must be in the SQL-92 syntax (the "where" clause part).
having used with Aggregate Functions. Sets a condition on a aggregate function to filter groups.
sortBy sets an array of column names to sort the data objects in the response by.
groupBy used with Aggregate Functions. Sets the name of a column to group the results by.
relations sets an array of related columns names. Objects from the related columns are included into the response.
relationsDepth sets the number of "levels" in the hierarchy of related objects to include into the response.
relationsPageSize A number of relation objects returned in response body.
fileReferencePrefix when FILE_REFERENCE column is in the table, then fileReferencePrefix  can be used to change the initial link to a file. For instance, a user can replace the current base path, to their custom domain where a file is stored, without updating any data in the table.

Blocking API

public List<BackendlessUser> findByRole( String roleName, boolean loadRoles, DataQueryBuilder queryBuilder )

Examples

Non-Blocking API

Backendless.UserService.findByRole(
        roleName, loadRoles, queryBuilder,
        new AsyncCallback<List<BackendlessUser>>()
        {
          @Override
          public void handleResponse( List<BackendlessUser> backendlessUsers )
          {
            // logic for processing retrieved users
          }

          @Override
          public void handleFault( BackendlessFault backendlessFault )
          {
            // exception handling logic
          }
        }
);

Blocking API

List<BackendlessUser> users = Backendless.UserService.findByRole( roleName, loadRoles, queryBuilder );

Retrieving User Roles By User ID

This method can be used both for custom and system roles and returns an array of all available user roles.

Non-Blocking API

public void getUserRoles( String userId, AsyncCallback<List<String>> responder )

where

Argument                Description
userId is a mandatory string argument.

Blocking API

public List<String> getUserRoles( String userId )

Examples:

Non-Blocking API

Backendless.UserService.getUserRoles(
        userId,
        new AsyncCallback<List<String>>()
        {
          @Override
          public void handleResponse( List<String> roleNames )
          {
            // logic for processing retrieved role names
          }

          @Override
          public void handleFault( BackendlessFault backendlessFault )
          {
            // exception handling logic
          }
        }
);

Blocking API

List<String> roleNames = Backendless.UserService.getUserRoles( userId );

Assigning a Role to a User

This operation is available only from Custom Business Logic. Applications must use the "Code Runner API key" in order for the API call to be  accepted on the server. The reason for this restriction is that a malicious use of this API can easily compromise application's security. As a result, this API must be used from a controlled environment.

Non-Blocking API

The method call does not block - it returns immediately. The AsyncCallback argument receives either the response or the fault returned by the Backendless servers.

public void Backendless.UserService.assignRole( String identity, 
                                                String roleName, 
                                                AsyncCallback<Void> callback );

where:

Argument                Description
identity a value for a user property marked as identity.
roleName the name of the role to assign to the user.
callback an object which receives either a return value or an error from the server. The class must implement the AsyncCallback<Void> interface.

Blocking API

public void Backendless.UserService.assignRole( String identity, String roleName ) 
                                                        throws BackendlessException;

where:

Argument                Description
identity user identification. A value for the property marked as identity.
roleName name of the role to assign to the user account.

Examples

Non-Blocking API

Backendless.UserService.assignRole( indentity, roleName, new AsyncCallback<Void>()
{
  @Override
  public void handleResponse( Void unused )
  {
    // on success logic
  }

  @Override
  public void handleFault( BackendlessFault backendlessFault )
  {
    // exception handling logic
  }
} );

Blocking API

Backendless.UserService.assignRole( indentity, roleName );

Unassigning a Role from a User

This operation is available only from Custom Business Logic. Applications must use the "Code Runner API key" in order for the API call to be  accepted on the server. The reason for this restriction is that a malicious use of this API can easily compromise application's security. As a result, this API must be used from a controlled environment.

Non-Blocking API

The method call does not block - it returns immediately. The AsyncCallback argument receives either the response or the fault returned by the Backendless servers.

public void Backendless.UserService.unassignRole( String identity, 
                                                  String roleName, 
                                                  AsyncCallback<Void> callback );

where:

Argument                Description
identity user identification. A value for the user property marked as identity.
roleName name of the role to remove from the user account.
callback an object which receives either a return value or an error from the server. The class must implement the AsyncCallback<Void> interface.

Blocking API

public void Backendless.UserService.unassignRole( String identity, String roleName ) 
                                                            throws BackendlessException;

where:

Argument                Description
identity user identity. A value for the user property marked as identity.
roleName name of the role to remove from the user account.

Examples

Non-Blocking API

Backendless.UserService.unassignRole( indentity, roleName, new AsyncCallback<Void>()
{
  @Override
  public void handleResponse( Void unused )
  {
    // on success logic
  }

  @Override
  public void handleFault( BackendlessFault backendlessFault )
  {
    // exception handling logic
  }
} );

Blocking API

Backendless.UserService.unassignRole( indentity, roleName );

Errors

The following errors may occur during the API calls described above. See the Error Handling section for details on how to retrieve the error code when the server returns an error.

Error Code
Description
2002
Version is disabled or provided wrong application info (application id or secret key)
2005
Could not find role.
3038
One of the required parameters (user identity or roleName) is null.
3057
Could not find user by id or identity.
3058
Could not assign role to user.
3059
Could not unassign role to user.