If you have followed the Symfony2 development, then you know that we had a feature at some point where you could secure individual controller actions in the <code>access_control</code> config section. Due to some implementation details that did not work reliably though, so we had to remove it.
The JMSSecurityExtraBundle has offered an alternative since then by allowing you to use @Secure, or @SecureParam annotations. Personally, I am using annotations quite heavily, but still there is a limitation in that you can only secure your own code this way. It is for example not possible to secure code provided by another bundle without overwriting the provided controller.
Some might counter that you can add hand-written code to your controller, something like
<?php
public function loginAction()
{
if ($this->container->get('security.context')->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
throw new AccessDeniedException();
}
// display login form...
}
Of course, that is a valid approach. The limitation of it is that you couple your business functionality with your security code which makes it less testable, and in case you are creating a third party bundle, the security logic is not easily customizable without copy/pasting the entire controller action.
In its upcoming version, the JMSSecurityExtraBundle will now allow you to configure method security not only with annotations, but also in the DI configuration. We can leverage the new expression-based authorization for this:
jms_security_extra:
expressions: ~
method_access_control:
'^FOSUserBundle:Login:login$': 'isAnonymous()'
<jms-security-extra expressions="true">
<method-rule pattern="^FOSUserBundle:Login:login$">isAnonymous()</method-rule>
</jms-security-extra>
As you can see, you can use the controller notation to specify which expression should be run before the action is executed. The key can be a regular expression either matching against a controller notation (like in the example above), or alternatively matching against the concatenation of the fully qualified class name, and the method name, e.g.:
jms_security_extra:
expressions: ~
method_access_control:
'LoginController::loginAction$': 'isAnonymous()'
<jms-security-extra expressions="true">
<method-rule pattern="LoginController::loginAction$">isAnonymous()</method-rule>
</jms-security-extra>
The second example, would not only secure the LoginController of the FOSUserBundle, but basically any controller with that name which has a loginAction method.
There are a lot of cool things you can do with this new feature, and some more examples are in the documentation.
Have fun!