Skip to content
This repository has been archived by the owner on Jul 3, 2020. It is now read-only.

Latest commit

 

History

History
200 lines (163 loc) · 5.87 KB

03. Role providers.md

File metadata and controls

200 lines (163 loc) · 5.87 KB

Role providers

In this section, you will learn:

  • What are role providers
  • What are identity providers
  • How to use and configure built-in providers
  • How to create custom role providers

What are role providers?

A role provider is an object that returns a list of roles. Each role provider must implement the ZfcRbac\Role\RoleProviderInterface interface. The only required method is getRoles, and must return an array of Rbac\Role\RoleInterface objects.

Roles can come from one of many sources: in memory, from a file, from a database... However, please note that since ZfcRbac 2.0, you can specify only one role provider per application. The reason is that having multiple role providers makes the workflow harder and can lead to security problems that are very hard to spot.

Identity providers?

Identity providers return the current identity. Most of the time, this means the logged in user. ZfcRbac comes with a default identity provider (ZfcRbac\Identity\AuthenticationIdentityProvider) that uses the Zend\Authentication\AuthenticationService service.

Create your own identity provider

If you want to implement your own identity provider, create a new class that implements ZfcRbac\Identity\IdentityProviderInterface class. Then, change the identity_provider option in ZfcRbac config, as shown below:

return [
    'zfc_rbac' => [
        'identity_provider' => 'MyCustomIdentityProvider'
    ]
];

The identity provider is automatically pulled from the service manager.

Built-in role providers

ZfcRbac comes with two built-in role providers: InMemoryRoleProvider and ObjectRepositoryRoleProvider. A role provider must be added to the role_provider subkey:

return [
    'zfc_rbac' => [
        'role_provider' => [
            // Role provider config here!
        ]
    ]
];

InMemoryRoleProvider

This provider is ideal for small/medium sites with few roles/permissions. All the data is specified in a simple PHP file, so you never hit a database.

Here is an example of the format you need to use:

return [
    'zfc_rbac' => [
        'role_provider' => [
            'ZfcRbac\Role\InMemoryRoleProvider' => [
                'admin' => [
                    'children'    => ['member'],
                    'permissions' => ['article.delete']
                ],
                'member' => [
                    'children'    => ['guest'],
                    'permissions' => ['article.edit', 'article.archive']
                ],
                'guest' => [
                    'permissions' => ['article.read']
                ]
            ]
        ]
    ]
];

The children and permissions subkeys are entirely optional. Internally, the InMemoryRoleProvider creates either a Rbac\Role\Role object if the role does not have any children, or a Rbac\Role\HierarchicalRole if the role has at least one child.

If you are more confident with flat RBAC, the previous config can be re-written to remove any inheritence between roles:

return [
    'zfc_rbac' => [
        'role_provider' => [
            'ZfcRbac\Role\InMemoryRoleProvider' => [
                'admin' => [
                    'permissions' => [
                        'article.delete',
                        'article.edit',
                        'article.archive',
                        'article.read'
                    ]
                ],
                'member' => [
                    'permissions' => [
                        'article.edit',
                        'article.archive',
                        'article.read'
                    ]
                ],
                'guest' => [
                    'permissions' => ['article.read']
                ]
            ]
        ]
    ]
];

ObjectRepositoryRoleProvider

This provider fetches roles from the database using Doctrine\Common\Persistence\ObjectRepository interface.

You can configure this provider by giving an object repository service name that is fetched from the service manager using the object_repository key:

return [
    'zfc_rbac' => [
        'role_provider' => [
            'ZfcRbac\Role\ObjectRepositoryRoleProvider' => [
                'object_repository'  => 'App\Repository\RoleRepository',
                'role_name_property' => 'name'
            ]
        ]
    ]
];

Or you can specify the object_manager and class_name options:

return [
    'zfc_rbac' => [
        'role_provider' => [
            'ZfcRbac\Role\ObjectRepositoryRoleProvider' => [
                'object_manager'     => 'doctrine.entitymanager.orm_default',
                'class_name'         => 'App\Entity\Role',
                'role_name_property' => 'name'
            ]
        ]
    ]
];

In both cases, you need to specify the role_name_property value, which is the name of the entity's property that holds the actual role name. This is used internally to only load the identity roles, instead of loading the whole table every time.

Please note that your entity fetched from the table MUST implement the Rbac\Role\RoleInterface interface.

Creating custom role providers

To create a custom role provider, you first need to create a class that implements the ZfcRbac\Role\RoleProviderInterface interface.

Then, you need to add it to the role provider manager:

return [
    'zfc_rbac' => [
        'role_provider_manager' => [
            'factories' => [
                'Application\Role\CustomRoleProvider' => 'Application\Factory\CustomRoleProviderFactory'
            ]
        ]    
    ]
];

You can now use it like any other role provider:

return [
    'zfc_rbac' => [
        'role_provider' => [
            'Application\Role\CustomRoleProvider' => [
                // Options
            ]
        ]
    ]
];

Navigation