RFC: Middleware on a per route basis

The latest work on Middleware and reading about implementation in different frameworks made me think about the following:

How about us being able to attach middleware on a per route basis

The idea is not groundbreaking science, it’s seen in many different cases and the concept is implemented elsewhere. So we have a lot of examples to lean up against and get smarter around.

More thougts

We have a defined set of middlewares at the moment. All “ending” in the dispatcher middleware, passing on the final response. And the dispatcher is being set (package, controller and action), based on a RoutingResults from the RoutingMiddleware being defined in Routes.yaml. This leading down to the MVC stack.

Here, we do all the rendering stuff. We check privileges based on Policy.yaml, firewall, and so on.

How about this.

I will like to disable the privilege/Policy part of the security framework in favor of my own middleware checking for a specific cookie or similar, to avoid a already registered user to call the “signup” endpoint of a api. But only on that particular route.

How? (I have ideas and no conclusion)

  • A seperate property in Route.yaml named middlewares: [] similar to httpMethods: []?
  • Your idea?

Hi @sorenmalling,

interesting thoughts, but I fear it’s a dangerous route to follow to be honest.

It’s a very common request to introduce “local” Settings (for example in order to have different dimension configurations per Neos Site). We never implemented that feature because it would introduce a whole lot of complexity and potential instability¹.

The middleware chain is a slightly different scenario of course, but I see similar dangers:

  • We would increase dependency between middlewares
  • It would only work for middlewares “inside” of the RoutingMiddleware
  • It would increase complexity

Having said that, nothing stops you from creating a custom middleware (“after routing”) that interprets the RoutingResults.

But in order to implement the usecase you described, you could instead just use a custom authentication provider and a Request pattern that only matches certain routes.

Or, if you just want to disable some “signup” endpoint for authenticated users, just disallow that like:

roles:
  'Neos.Flow:Anonymous':
    privileges:
      -
        privilegeTarget: 'Your.Package:Signup.Privilege'
        permission: GRANT

Won’t that work for you?


¹ Not directly related to your request but in case someone wonders: Regarding the local Settings for multiple Neos sites we could implement support for that just for the dimension configuration theoretically. But next requirement is: custom node types per site and it doesn’t stop there. So I would suggest that we instead make it easier to inter-connect multiple Neos instances (i.e. support SSO and cross-site-linking with external sites) in the long term instead.

I think that the simplicity of the single chain is an advantage of the current solution. Because it allows to easily reflect about the processing order of a request.

In addition you can already add a middleware between routing and dispatching and let it do nothing unless specific routing parameters are set. So if you need this you can implement it. Unless we find a very common usecase i would prefer not to add additional compexity here

1 Like