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 for the Book entity.
2 All actions are allowed. FixedEntityAllowableActionsBuilder.DEFAULT_ALLOWABLE_ACTIONS always acknowledges that the requested action is present.
3 Configuring the actions for the Book instance.
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

building-views/list-view.adoc#list-view

AllowableAction.READ

global

building-views/form-view.adoc#create-view

AllowableAction.CREATE

global

building-views/form-view.adoc#detail-view

AllowableAction.READ

instance

building-views/form-view.adoc#update-view

AllowableAction.UPDATE

instance

building-views/form-view.adoc#delete-view

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.

Each of the default views is linked via the list view. These links depend on the presence of the required action, except for detail views:

  • If access to the detail view is allowed, but not to the update view, a link to the detail view will be available.

  • If access to the update view is allowed, a link to the update view will be available but not to the readonly view.

This can be overridden by setting the EntityAttributes.LINK_TO_DETAIL_VIEW to true. If set, the list view will link to the detail view if the user has the read action, but never to the update view by default.

Configuring a list view

By default a list view is configured to be accessible if the global AllowableAction.READ action is present. If a user does not have access to the other actions, the list view will still be available, but links to the other views will not be provided on the list view. This means that even though the user may not have AllowableAction.READ access for a specific instance, he can still see the data presented in the list view itself.

By configuring the showOnlyItemsWithAction on a list view, the individual entries of the list can also be filtered based on the given action.

Filtering a list by an action
configuration.withType( Book.class )
             .listView( lvb -> lvb.showOnlyItemsWithAction( AllowableAction.READ ) ); (1)
1 Only book items for which the current principal has the instance action AllowableAction.READ will be visible in the list view.

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.