I have added a custom access check to the /user/{user} route:

class RouteSubscriber extends RouteSubscriberBase {

   * {@inheritdoc}
  protected function alterRoutes(RouteCollection $collection) {
    if ($route = $collection->get('entity.user.canonical')) {
      $route->setRequirement('_profile_access', '\Drupal\mymodule\Access\ProfileAccessCheck::access');


with some starter checks:

 * Determines access to user profile based on conditions.
class ProfileAccessCheck implements AccessInterface {

   * Checks if this profile is publicly visible.
   * @param \Drupal\Core\Routing\RouteMatch $routeMatch
   * @return \Drupal\Core\Access\AccessResultAllowed|\Drupal\Core\Access\AccessResultForbidden
  public function access(RouteMatch $routeMatch) {
    $requested_profile = $routeMatch->getParameter('user');
    $show_profile = (bool) $requested_profile->field_show_profile->value;

    if ($show_profile === TRUE) {
      return AccessResult::allowed();

    return AccessResult::forbidden();


This appears to work fine, although it seems that the "View" tab does not hide/show in the admin when saving a user. If I clear the site cache, the tab is there on a user edit (or not, depending on value). Is there a way to get it to bind to the user or is it not worth while?


Turns out I just had to chain it to the AccessResult like so:


Same for forbidden(). Now the 'View' tab is visible appropriately.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.