hvtilborg
hvtilborg

Reputation: 1477

Hide routes that are only used for subrequests in Silex

I've created a route sitemap that shows the site's sitemap. This sitemap is included at almost every page using the following Twig construction:

{% if app.debug %}
{{ render(path('sitemap')) }}
{% else %}
<esi:include src="{{ path('sitemap') }}" />
{% endif %}

So that in debug I'll see the page too. This works perfect. Although, the sitemap is also reachable using /sitemap. How can I avoid this? I.e. is there a way that I can make the sitemap route only available for subrequests?

Upvotes: 1

Views: 1393

Answers (2)

Mick
Mick

Reputation: 31959

Adding this to your security.yml file will allow you to secure your controller:

access_control:
    - { path: ^/private, roles: IS_AUTHENTICATED_ANONYMOUSLY, ip: 127.0.0.1  }
    - { path: ^/private, roles: ROLE_NO_ACCESS }

And then put your controller under a path that starts with /private:

<route id="whatever" pattern="/private/sitemap">
        <default key="_controller">AcmeDemoBundle:Sitemap:whatever</default>
</route>

This is a general way to secure all your sub-requests that will start with /private, so that people can not access /private/sitemap. Embedding the controller will work as the request will be made by your server ( 127.0.0.1 via the loopback interface).


  • You can now secure any sub-requests in the same way using /private attribute in the beginning of your URLs.
  • The order of these elements in your access list matters. I generally put the very secure elements at the top of the list.

Upvotes: 1

Maerlyn
Maerlyn

Reputation: 34105

Somehow you need to check if the currently handled request is a master or a sub-request. This is correctly set by render, then passed down to handle, then to the kernel. Unfortunately, there's no easy way to get the type from your controller (or a middleware).

The HttpKernel emits the KernelEvents::CONTROLLER event after parsing the request, but before executing the controller. This gets the request type.

If you write an event listener like this, you can still abort:

use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;

$app["dispatcher"]->addListener(KernelEvents::CONTROLLER, function (FilterControllerEvent $event) use ($app) {
    $internals = array("sitemap");
    $route = $event->getRequest()->get("_route");

    if (in_array($route, $internals) && $event->getRequestType() == HttpKernelInterface::SUB_REQUEST) {
        return $app->abort(403);
    }
});

Upvotes: 1

Related Questions