There's no specific functionality for that yet: https://github.com/cakephp/authentication/issues/316
It could be solved in many different ways, personally I have done this before by catching Authentication\Authenticator\UnauthenticatedException
in an extended authentication component, by overwriting \Authentication\Controller\Component\AuthenticationComponent::doIdentityCheck()
:
<?php
// src/Controller/Component/AppAuthenticationComponent.php
/*
load in `AppController::initialize()` via:
$this->loadComponent('Authentication', [
'className' => \App\Controller\Component\AppAuthenticationComponent::class,
]);
*/
namespace App\Controller\Component;
use Authentication\Authenticator\UnauthenticatedException;
use Authentication\Controller\Component\AuthenticationComponent;
use Cake\Controller\Component\FlashComponent;
/**
* @property FlashComponent $Flash
*/
class AppAuthenticationComponent extends AuthenticationComponent
{
public $components = [
'Flash'
];
protected function doIdentityCheck(): void
{
try {
parent::doIdentityCheck();
} catch (UnauthenticatedException $exception) {
$this->Flash->error(__('You must be logged in to access this page.'));
throw $exception;
}
}
}
You could also do it manually in your app controller, for that you'd have to disable the plugin component's automatic identity check, and do that check on your own:
// src/Controller/AppController.php
public function initialize(): void
{
parent::initialize();
$this->loadComponent('Authentication.Authentication', [
'requireIdentity' => false
]);
}
public function beforeFilter(EventInterface $event)
{
parent::beforeFilter($event);
$action = $this->request->getParam('action');
if (
!in_array($action, $this->Authentication->getUnauthenticatedActions(), true) &&
!$this->Authentication->getIdentity()
) {
$this->Flash->error(__('You must be logged in to access this page.'));
throw new UnauthenticatedException('No identity found.');
}
}