I don’t know why, but here is my middleware
/**
* Setup the middleware queue your application will use.
*
* @param \Cake\Http\MiddlewareQueue $middlewareQueue The middleware queue to setup.
* @return \Cake\Http\MiddlewareQueue The updated middleware queue.
*/
public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue
{
$securityHeaders = new SecurityHeadersMiddleware();
$securityHeaders
->setCrossDomainPolicy()
->setReferrerPolicy()
->setXFrameOptions()
->setXssProtection()
->noOpen()
->noSniff();
$csrf = new CsrfProtectionMiddleware([
'httponly' => true,
'secure' => true,
]);
$middlewareQueue
// Security Header Middleware
->add($securityHeaders)
// HTTPS Enforcer Middleware
->add(new HttpsEnforcerMiddleware([
'hsts' => ['maxAge' => 31536000, 'includeSubDomains' => true],
]))
// Catch any exceptions in the lower layers,
// and make an error page/response
->add(new ErrorHandlerMiddleware(Configure::read('Error'), $this))
// Handle plugin/theme assets like CakePHP normally does.
->add(new AssetMiddleware([
'cacheTime' => Configure::read('Asset.cacheTime'),
]))
// Add routing middleware.
// If you have a large number of routes connected, turning on routes
// caching in production could improve performance.
// See https://github.com/CakeDC/cakephp-cached-routing
->add(new RoutingMiddleware($this))
// Parse various types of encoded request bodies so that they are
// available as array through $request->getData()
// https://book.cakephp.org/4/en/controllers/middleware.html#body-parser-middleware
->add(new BodyParserMiddleware())
// Cross Site Request Forgery (CSRF) Protection Middleware
// https://book.cakephp.org/4/en/security/csrf.html#cross-site-request-forgery-csrf-middleware
->add($csrf)
// Add the AuthenticationMiddleware. It should be
// after routing and body parser.
->add(new AuthenticationMiddleware($this))
// Add the AuthorizationMiddleware *after* routing, body parser
// and authentication middleware.
->add(new AuthorizationMiddleware($this, [
'unauthorizedHandler' => [
'className' => 'Authorization.Redirect',
'url' => Router::url([
'prefix' => 'Pages/Web',
'plugin' => null,
'controller' => 'Auth',
'action' => 'login',
]),
'queryParam' => 'redirect',
'exceptions' => [
MissingIdentityException::class,
ForbiddenException::class
],
],
]))
->add(new RequestAuthorizationMiddleware());
return $middlewareQueue;
}
and authorization service
/**
* Returns a service provider instance.
*
* @param \Psr\Http\Message\ServerRequestInterface $request Request
* @return \Authorization\AuthorizationServiceInterface
*/
public function getAuthorizationService(ServerRequestInterface $request): AuthorizationServiceInterface
{
$mapResolver = new MapResolver();
$mapResolver->map(ServerRequest::class, RequestPolicy::class);
return new AuthorizationService($mapResolver);
}