Conversely, how I can prevent anyone from getting to user/* pages?
Getting technical here, you wouldn't want to block all /user/*
; otherwise, you wouldn't be able to /user/login
or /user/logout
and also you would still want admins to access those /user/{uid}
pages.
If you inspect core/modules/user/user.routing.yml you can see most of the user routes. But what you expect, the /user/{uid}
is not defined here.
It's actually defined in UserRouteProvider.php as /user/{user}

You can easily find the route name by enabling WebProfiler module that comes with Devel and going to /user/1

Now all you gotta do is override the route's access by giving it a role of administrator.
mymodule/src/Routing/RouteSubscriber.php
namespace Drupal\mymodule\Routing;
use Drupal\Core\Routing\RouteSubscriberBase;
use Symfony\Component\Routing\RouteCollection;
/**
* Listens to the dynamic route events.
*/
class RouteSubscriber extends RouteSubscriberBase {
/**
* {@inheritdoc}
*/
protected function alterRoutes(RouteCollection $collection) {
// Allow only admins to access '/user/{user}'.
if ($route = $collection->get('entity.user.canonical')) {
$route->setRequirement('_role', 'administrator');
}
}
}
Alternatively, in your custom module, you could create a new permission and use that for the Route's setRequirement
instead and then assign the new permission to the roles that you want to have access.
mymodule/mymodule.services.yml
services:
mymodule.route_subscriber:
class: Drupal\mymodule\Routing\RouteSubscriber
tags:
- { name: event_subscriber }
For more in depth information about altering routes, see: Altering existing routes and adding new routes based on dynamic ones.