Reputation: 1477
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
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).
/private
attribute in the beginning of your URLs.Upvotes: 1
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