This section will teach you how to use the AuthorizationService to its full extend.
To automatically inject the authorization service into your classes, you can implement the
AuthorizationServiceAwareInterface
and use the trait, as shown below:
namespace YourModule;
use ZfcRbac\Service\AuthorizationServiceAwareInterface;
use ZfcRbac\Service\AuthorizationServiceAwareTrait;
class MyClass implements AuthorizationServiceAwareInterface
{
use AuthorizationServiceAwareTrait;
public function doSomethingThatRequiresAuth()
{
if (! $this->getAuthorizationService()->isGranted('deletePost')) {
throw new UnauthorizedException('You are not allowed !');
}
return true;
}
}
Then, registers the initializer in your config (it is not by default):
class Module
{
// ...
public function getServiceConfig()
{
return [
'initializers' => [
'ZfcRbac\Initializer\AuthorizationServiceInitializer'
]
];
}
}
While initializers allow rapid prototyping, it can leads to more fragile code. We'd suggest using factories.
ZfcRbac is shipped with a ZfcRbac\Factory\AuthorizationServiceDelegatorFactory
[delegator factory]
(http://framework.zend.com/manual/2.3/en/modules/zend.service-manager.delegator-factories.html)
to automatically inject the authorization service into your classes.
As for the initializer, the class must implement the AuthorizationServiceAwareInterface
.
You just have to add your classes to the right delegator :
class Module
{
// ...
public function getServiceConfig()
{
return [
'invokables' => [
'Application\Service\MyClass' => 'Application\Service\MyClassService',
],
'delegators' => [
'Application\Service\MyClass' => [
'ZfcRbac\Factory\AuthorizationServiceDelegatorFactory',
// eventually add more delegators here
],
],
];
}
}
While they need a little more configuration, delegators factories have better performances than initializers.
You can inject the AuthorizationService in your factories by using Zend's ServiceManager. The AuthorizationService
is known to the ServiceManager as 'ZfcRbac\Service\AuthorizationService'
. Here is a classic example for injecting
the AuthorizationService:
YourModule/Module.php
class Module
{
// getAutoloaderConfig(), etc...
public function getServiceConfig()
{
return [
'factories' => [
'MyService' => function($sm) {
$authService = $sm->get('ZfcRbac\Service\AuthorizationService');
return new MyService($authService);
}
]
];
}
}
DI is a great way for prototyping, getting results fast and maintaining a flexible structure. However it adds overhead and can get very slow. Unless you are using a compiler it is not recommended for production. Here's how you enable Zend\DI to inject the AuthorizationService in MyClass:
YourModule/Module.php
namespace YourModule;
class Module
{
// getAutoloaderConfig(), etc...
public function getConfig()
{
return [
'di' => [
'definition' => [
'class' => [
__NAMESPACE__ . '\MyClass' => [
'setAuthorizationService' => [
'required' => true
]
]
]
]
]
];
}
}
Since you now know how to inject the AuthorizationService, let's use it!
One of the great things the AuthorizationService brings are assertions. Assertions get executed if the identity
in fact holds the permission you are requesting. A common example is a blog post, which only the author can edit. In
this case, you have a post.edit
permission and run an assertion checking the author afterwards.
The AssertionPluginManager is a great way for you to use assertions and IOC. You can add new assertions quite easily
by adding this to your module.config.php
file:
return [
'zfc_rbac' => [
'assertion_manager' => [
'factories' => [
'MyAssertion' => 'MyAssertionFactory'
]
]
]
];
The assertion map can automatically map permissions to assertions. This means that every times you check for a
permission with an assertion map, you'll include the assertion in your check. You can define the assertion map by
adding this to your module.config.php
file:
return [
'zfc_rbac' => [
'assertion_map' => [
'myPermission' => 'myAssertion'
]
]
];
Now, everytime you check for myPermission
, myAssertion
will be checked as well.
So let's check for a permission, shall we?
$authorizationService->isGranted('myPermission');
That was easy, wasn't it?
isGranted
checks if the current identity is granted the permission and additionally runs the assertion that is
provided by the assertion map.
ZfcRbac comes with both a controller plugin and a view helper to check permissions.
In a controller :
public function doSomethingAction()
{
if (!$this->isGranted('myPermission')) {
// redirect if not granted for example
}
}
In a view :
<?php if ($this->isGranted('myPermission')): ?>
<div>
<p>Display only if granted</p>
</div>
<?php endif ?>
But what if you don't want to use the assertion map? That's quite easy as well!
Here are four use cases on how you can work without the assertion map:
Disable the assertion:
$authorizationService->setAssertion('myPermission', null);
$authorizationService->isGranted('myPermission');
Callback assertion:
$something = true;
$authorizationService->setAssertion(
'myPermission',
function(AuthorizationService $authorization, $context = true) use ($something) {
return $something === $context
}
);
$authorizationService->isGranted('myPermission'); // returns true, when the identity holds the permission `myPermission`
Object implementing AssertionInterface
:
$context = true;
$authorizationService->setAssertion('myPermission', new MyAssertion($foo, $bar));
$authorizationService->isGranted('myPermission', $context);
Using the AssertionPluginManager:
$context = true;
$authorizationService->setAssertion('myPermission', 'MyAssertion');
$authorizationService->isGranted('myPermission', $context);
Please note: The context parameter is optional!
- Continue to [the Cookbook](/docs/07. Cookbook.md)
- Back to [the Strategies](/docs/05. Strategies.md)
- Back to the Index