If I use Router:: , I get a Missing error, apparently the Router is not available, while the documentation says that it is, where is the problem please?
I don’t quite understand, I have the same route in the authenticator that works. It doesn’t work here, if we put the url there eg ‘/user/login’ it works, but not when using Route.
/**
* 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);
}
No routes are being loaded until the routing middleware runs, so you cannot use the router at that point, you are calling it in the context of the middleware() call, not in the context of the authorization middleware actually running. It works in getAuthenticationService() because that method is being invoked when the authentication middleware actually runs, which happens after the routing middleware runs.
Note that the docs do not state that you can use the Router::url() in the authorization config, what they do state is that you can pass routing URL arrays to the url option when using the CakeRedirect handler (as apposed to the regular Redirect handler):