JMSSecurityExtraBundle 1.3 introduces @SecurityFunction
By Emily Newsom
We're currently investing development resources into an upcoming open-source Symfony2 based project. A few of my favorite bundles are JMSDiExtraBundle and JMSSecurityExtraBundle from Johannes Schmitt, both of which come with the default vendor release of Symfony2. JMSDiExtraBunde gives you the ability to put nice annotations right beside your service and controller code--information that would otherwise be stored off in yet another yaml file (not that I hate yaml! ;). JMSSecurityExtraBundle builds on JMSDiExtraBundle and gives you security related annotations as well as a cool expression language.
For example, one can do things like this:
class InstallerController extends ContainerAware { ... /** * @PreAuthorize("hasRole('FOO') or hasRole('BAR')") */ public function checkAction() { ... } }
Which will check that the current user has role FOO or BAR. There are many other expressions one can use and they're all listed on Johannes' site.
But what really caught my eye was the new feature that he made available in his new 1.3 version--@SecurityFunction. There's a small note on the bottom of his annotation reference page about the new annotation and a small example, but it was still a little unclear exactly how one uses @SecurityFunction. Basically @SecurityFunction gives you the ability write your own functions that can be used in any expression. So in our above example, hasRole() is a security function. If we defined our own security function fooBar() then we could use fooBar() just like we used hasRole() in the above example.
So where do you define your @SecurityFunction? Well, to me it seems to make the most sense to place these in a related service. In my case, I have a service Installer where I placed a security function isInstalled()
/** * @Service("acme.demo.installer") */ class Installer { ... /** * @SecurityFunction("isInstalled") */ public function isInstalled() { // We injected $this->installed earlier on return $this->installed; } }
Now I can go into any of my controller actions and do this:
class InstallerController extends ContainerAware { ... /** * @PreAuthorize("!isInstalled()") */ public function installAction() { ... } }
Which makes for a nice way to secure your actions with your own security checks before control even reaches your controller action code.
Note that @SecurityFunction is available in 1.3 and beyond (currently a dev release).
Not quite ready to take the plunge?
Subscribe if you're looking for help but aren't quite ready. We'll keep you informed of our availability and special promotions.