Redirect to intercepted request resulting in "wrong" URL

Facing an interesting issue here. In a Neos site (v7.3) I am checking permission to see a node using an around aspect on Frontend/NodeController->showAction(). If the permission check fails, that aspect throws an AuthenticationRequiredException.

That is caught in Dispatcher->disptach() and there the $request is attached to the exception using $exception->attachInterceptedRequest($request). From there on, all that happens is “default behaviour” of Flow and Neos…

SecurityEntryPointMiddleware->process() calls $this->securityContext->setInterceptedRequest($authenticationException->getInterceptedRequest()) and the calls $entryPoint->startAuthentication($request, $response). The entrypoint is custom, but does not influence the stored intercepted request (it is doing what the WedRedirect does, just determining the route values differently.)

I end up at the login screen (a Neos document having a login form plugin) and after submitting that, I get rediretced to the document I tried to open originally. It shows as expected, but the URL is “wrong”.

Instead of

I end up at

The values are correct, just the argument namespace is wrong, and thus the “wrong” URL is generated by the routing.

Digging deeper I found that the namespace is added in UriBuilder->addNamespaceToArguments() which is called using $this->request in UriBuilder->uriFor().

Now, $this->request is the request from submitting the login form (set in AbstractController->initializeController()), thus it has an argument namespace, that “wins” over the intercepted request.

Ok, next try is to use $this->uriBuilder->setRequest($originalRequest) in my AuthenticationController->onAuthenticationSuccess() method before handing over to $this->redirectToRequest($originalRequest). Which leads to a new exception:

Exception in line 367 of /…/Neos_Flow_Mvc_Routing_UriBuilder.php: Return value of Neos\Flow\Mvc\ActionRequest_Original::getHttpRequest() must implement interface Psr\Http\Message\ServerRequestInterface, null returned - See also: 20230814134033198342.txt

Indeed, the stored intercepted request has no HTTP request attached (removed upon serialization using __sleep()), but the method must return one.

I then tried using build() instead of uriFor(), but the problem resurfaces in a different way, since that calls mergeArgumentsWithRequestArguments(), which in turn calls addNamespaceToArguments()

Now, did anyone ever have this issue? If yes, (how) was it solved?

I ended up with this code now… :sob:

if ($originalRequest !== null) {
    $httpRequest = new ServerRequest('GET', 'https://localhost');
    $httpRequest = $httpRequest->withAttribute(
        RouteParameters::createEmpty()->withParameter('requestUriHost', $httpRequest->getUri()->getHost())
    $uriBuilder = new UriBuilder();

    $uri = $uriBuilder

Why, oh, why… it should be as easy as:


Ok, I dug a bit further, together with @christianm. The result is

that can make this easier for the developer.

Going further we could instead store just the intercepted URI or the HTTP request, as mentioned in the issue.

1 Like