Custom Access Checking on Routes (Custom Access Callback)

To create a custom access check on a route all you need to do is create a service that implements AccessInterface and use that to check access. Then in your routing.yml file enter the string that is returned by the appliesTo() method as the requirements. An example below of creating custom access checking on routes.

Add custom permission in routing.yml

your_module.some_page:
  path: '/path/to/page'
  defaults:
    _controller: '\Drupal\your_module\Controller\ControllerClassName::build'
    _title: 'My Title'
  requirements:
    _my_custom_access_check: 'TRUE'

Add the service to module.services.yml

  my_module.my_custom_access_check:
    class: Drupal\my_module\MyCustomAccessCheck
    arguments: ['@current_user']
    tags:
      - { name: access_check, applies_to: _my_custom_access_check }

Create the service Class

<?php

namespace Drupal\my_module;

use Drupal\Core\Access\AccessResult;
use Drupal\Core\Routing\Access\AccessInterface;
use Drupal\Core\Session\AccountInterface;
use Symfony\Component\Routing\Route;
use Symfony\Component\HttpFoundation\Request;

/**
 * Class MyCustomAccessCheck.
 *
 * @package Drupal\my_module
 */
class MyCustomAccessCheck implements AccessInterface {

  public function appliesTo() {
    return '_my_custom_access_check';
  }

  public function access(Route $route, Request $request, AccountInterface $account) {
    // Add your checks here and return the below accordingly.
    return AccessResult::allowed();
    //return AccessResult::forbidden();
    //return AccessResult::neutral();
  }

}

Below are some non-custom ways of adding access checks:

By role

your_module.some_page:
  path: '/path/to/page'
  defaults:
    _controller: '\Drupal\your_module\Controller\ControllerClassName::build'
    _title: 'My Title'
  requirements:
    _role: 'administrator'

By Permission

your_module.some_page:
  path: '/path/to/page'
  defaults:
    _controller: '\Drupal\your_module\Controller\ControllerClassName::build'
    _title: 'My Title'
  requirements:
    _permission: 'access content'