Skip to content
Field note

Custom Access Check on Routes in Drupal 8

Introduction

January 27, 2020·2 min read·Gaurav Agrawal, PHP/Drupal Engineer - L3/ Field correspondent
Custom Access Check on Routes in Drupal 8

Introduction

Recently in Drupal 8, we encountered a situation where we had to restrict access to an existing route based on some custom permissions for a specific role.

The route which we wanted to restrict was block_content.add_form from core block_content module. Below is the reference of the code from block_content.routing.yml:

Currently, there is a single permission Administer block available, which grants access to manage all available block types. So a role that has this permission can manage all block types. But we wanted to limit the creation of some block types for a particular role.

To make it more clear, consider the below scenario:

  • Let's say we have the following custom block types: Foo (machine name: foo), Bar (machine name: bar), Basic (core).
  • There are two roles Block manager and Block creator with required permissions to administer blocks and Access admin theme.

The objective is to allow a user of a specific role to create a block content of type X if and only if that role has the create X block content permission.

We did this by creating a custom access check for block_content.add_form route in a custom example module.
To start with we defined custom permissions in example.permissions.yml for each block type respectively so that based on it, we can put an access check.

example.permissions.yml

After the permissions are defined, now it's time to register a custom service access_check.block.add for custom access check and register a Route subscriber.

example.services.yml

Our route subscriber alters the existing route block_content.add_form from the core block module. This is the key step required to add the access checks we want on an existing route.

RouteSubscriber.php

Route::setRequirement() is used to set custom access checks on the route we want within the alterRoutes function. In our case, it adds check to the block_content.add_form route.

ExampleAccessCheck.php

The path in route contains the slug block_content_type which is the machine name of the block type.

$block_content_type is available in access method and this helps to determine if the role has required permissions to access the route for each block type respectively.

example.info.yml

Directory Structure

Enabling the Example module defines the following permissions:

  • create bar block content
  • create basic block content
  • create foo block content

Now, If we login without either a Block creator or a Block manager role and try to add a custom block of any block type it will simply return Access denied.


The particular role will be able to create the custom block of type X, only if the Create X block permission is given to the role.

The above example explains how we can add custom Access checks to block_content.add_form route and similarly we can add custom checks to other routes as well.


Here is the git repo for the example module in case you want to play around with it.

Companion brief

Bring this dispatch into a working session - one page in, scoping memo out.

Brief Foyer
Pressure-test "Field note" with a partner

If this dispatch landed, bring it into a room with us.

The argument in "Custom Access Check on Routes in Drupal 8" is ours - but every situation breaks the argument differently. Send the situation in one page and a named partner will reply inside one business day with a scoping memo: where the argument holds for you, where it bends, and what we'd actually do in the first two weeks.

One-pager · Field note

By submitting this form you acknowledge that you have read Axelerant's Privacy Policy and agree to its terms.

Replied to by a named partner within one business day.