Security and Permissions

EntityModule provides base security by integrating with the AllowableAction model of SpringSecurityModule. Allowable actions define which actions an end user can perform on an item or a type. These actions are by default specified in two aspects:

  • The allowable actions specified on the EntityConfiguration

  • The allowable actions specified on a view

Allowable actions for an EntityConfiguration

Actions specified on an entity configuration specify which actions a user may perform on an entity type or instance. These actions can be fixed, for example no user can delete books via the default interface, as well as depend on custom rules, for example based on the roles of the current user.

The actions on an EntityConfiguration are separated on two levels:

  • global actions: actions that are present for an entity type.

  • instance actions: actions that are present based on a specific instance for an entity type.

These can be configured by specifying the allowableActionsBuilder when customizing the EntityConfiguration.

Default allowable actions are specified on each configuration which confirm that any requested action is present.
Example allowable actions builder
configuration.withType( Book.class )
             .allowableActionsBuilder( new EntityConfigurationAllowableActionsBuilder()
             {
	             @Override
	             public AllowableActions getAllowableActions( EntityConfiguration<?> entityConfiguration ) { (1)
		             return FixedEntityAllowableActionsBuilder.DEFAULT_ALLOWABLE_ACTIONS; (2)
	             }

	             @Override
	             public <V> AllowableActions getAllowableActions( EntityConfiguration<V> entityConfiguration, V entity ) { (3)
		             return new AllowableActionSet( AllowableAction.READ.getId(), AllowableAction.UPDATE.getId() ); (4)
	             }
             } )
1 Configuring the global actions.
2 All actions are allowed. FixedEntityAllowableActionsBuilder.DEFAULT_ALLOWABLE_ACTIONS always acknowledges that the requested action is present.
3 Configuring the instance actions.
4 The actions are configured based on a custom implementation. In this case each instance has the AllowableAction.READ and AllowableAction.UPDATE action.
Example allowable actions based on roles
   private final CurrentSecurityPrincipalProxy currentSecurityPrincipalProxy;

configuration.withType( Book.class )
             .allowableActionsBuilder( new EntityConfigurationAllowableActionsBuilder()
             {
	             @Override
	             public AllowableActions getAllowableActions( EntityConfiguration<?> entityConfiguration ) {
	                 AllowableActionSet allowableActions = new AllowableActionSet();
	                 if( currentSecurityPrincipalProxy.hasAuthority( "ROLE_ADMIN" ){ (1)
	                    allowableActions.add( AllowableAction.CREATE );
	                 }
	                 allowableActions.add( AllowableAction.READ );
		         return allowableActions;
	             }

	             @Override
	             public <V> AllowableActions getAllowableActions( EntityConfiguration<V> entityConfiguration, V entity ) {
	                AllowableActionSet allowableActions = new AllowableActionSet();
	             	if( currentSecurityPrincipalProxy.hasAuthority( "ROLE_ADMIN" ) ) { (2)
	             	    allowableActions.add( AllowableAction.UPDATE );
	             	    allowableActions.add( AllowableAction.DELETE );
	             	}
	                 allowableActions.add( AllowableAction.READ );
		          return allowableActions;
	             }
             } )
1 Only administrators can create new books.
2 Only administrators can modify or delete books.
Actions specified on the configuration can be used by other components of the application, such as the various views provided by EntityModule.

Securing views

Actions for default views

The action registered on a view specifies which action must be present for a view to be accessible by a user. For each of the default views, a required action is configured.

Table 1. Actions on default views
View name Required action Level

listView

AllowableAction.READ

global

createView

AllowableAction.CREATE

global

updateView

AllowableAction.UPDATE

instance

deleteView

AllowableAction.DELETE

instance

If the current user does not have access to the action required for the view, then he will not have access to the page itself.

When the default views are rendered, these actions are also checked when links to different views are provided. This means that, for example, whilst rendering the list view, each instance is checked for the presence of the AllowableAction.UPDATE and AllowableAction.DELETE action before rendering the buttons to the corresponding pages.

Configuring custom views

The default views all have an action configured to access the view. When creating custom views, they can be secured by providing an access validator or specifying a required action.

Providing an access validator
configuration.withType( Book.class )
             .formView( "custom-view", EntityViewCustomizers.basicSettings() (1)
                   				             .adminMenu( "/custom-view" )
                   				             .accessValidator( ( viewFactory, viewContext ) -> viewContext.getAllowableActions().contains( AllowableAction.ADMINISTER ) ) (2)

                   		             )
1 A custom view is configured with basic view settings. EntityViewCustomizers provides base consumers that support common scenario’s, such as adding an admin menu for the current view.
2 An access validator is specified that checks whether the AllowableAction.ADMINISTER is available.

In previous example, a menu item was immediately registered for our custom view. Both the view and the menu item were secured via the specified access validator.

In the following example, we’ll create an equal configuration by specifying the required action for the view. The sole difference between the two examples is that the latter will not create a menu item.

Specifying a required action
configuration.withType( Book.class )
             .formView( "custom-view", fvb -> fvb.requiredAllowableAction( AllowableAction.ADMINISTER ) ) (1)
1 A custom view is configured, secured with the AllowableAction.ADMINISTER action.

When the access to the view is checked, one of the following scenario’s applies:

  • An instance is present in the current view context, as such the instance will be checked for the required action.

  • No instance is present in the current view context, as such the current EntityConfiguration will be checked for the required action.