项目作者: geggleto

项目描述 :
PSR-7 Zend ACL implementation - Permission Library [ slim, psr7, acl, permissions, zend ]
高级语言: PHP
项目地址: git://github.com/geggleto/geggleto-acl.git
创建时间: 2016-01-04T21:00:19Z
项目社区:https://github.com/geggleto/geggleto-acl

开源协议:MIT License

下载


Build Status

geggleto-acl

Provides a ACL repository and Middleware using Zend/Permissions/Acl library
PSR-7 Compliant

How it works

  • Resources are end-points
  • Roles are a group of resources
  • You can either allow or deny those roles.

The roles a user has are loaded into the AclRepo on every request. I suggest loading them into a session variable rather than pulling them from storage everytime (usage case depending).

The current route is then inspected and compared to the list of accessable resources in a middleware. a 401 is returned if a user is not allowed. If the user is allowed the application is allowed to continue.

By default no message body is provided on the 401, and if you require a page to be rendered then you will need to write your own middleware.

Usage Example

  1. //Define or Pull your ACL's into the following format
  2. /*
  3. $config = [
  4. "resources" => ["/", "/no", "/yes"],
  5. "roles" => ["guest", "user1", "user2"],
  6. "assignments" => [
  7. "allow" => [
  8. "guest" => ["/"],
  9. "user1" => ["/", "/no"],
  10. "user2" => ["/", "/yes"]
  11. ],
  12. "deny" => [
  13. "guest" => ["/no", "/yes"],
  14. "user1" => ["/yes"],
  15. "user2" => ["/no"]
  16. ]
  17. ]
  18. ];
  19. */
  20. //In Slim v3
  21. $app->add(\Geggleto\Acl\AclRepository(["guest"],
  22. //This should be in a nice php file by itself for easy inclusion... include '/path/to/acl/definition.php'
  23. [
  24. "resources" => ["/", "/no", "/yes"],
  25. "roles" => ["guest", "user1", "user2"],
  26. "assignments" => [
  27. "allow" => [
  28. "guest" => ["/"],
  29. "user1" => ["/", "/no"],
  30. "user2" => ["/", "/yes"]
  31. ],
  32. "deny" => [
  33. "guest" => ["/no", "/yes"],
  34. "user1" => ["/yes"],
  35. "user2" => ["/no"]
  36. ]
  37. ]
  38. ]));

Dynamic Routes

In the case where your resource changes, it is possible to still correctly match by setting a resources with a Route Pattern.
By default the system will inspect the $request’s ‘route’ attribute and this Object should return the route pattern with ->getPatter();
Out of the box this will work with Slim 3 routes if you have turned on the ‘determineRouteBeforeAppMiddleware’ => true option.

Example Config:

  1. return [
  2. "resources" => ["/", "/login", "/grid", "/404", "/logout", "/roles", "/roles/{pein}"],
  3. "roles" => ["guest", "grid", "roles"],
  4. "assignments" => [
  5. "allow" => [
  6. "guest" => ["/", "/404", "/login"],
  7. "grid" => [ '/grid', '/logout' ],
  8. "roles" => ['/roles', '/roles/{pein}']
  9. ],
  10. "deny" => []
  11. ]
  12. ];

If this does not fit your usage, feel free to override the default handler by setting your own via setHandler(callable)

Middleware

You can use the repo class directly which contains this code block… or modify this code block to suit your needs.

  1. $app->add(function (Request $request, Response $res, $next) {
  2. /** @var $aclRepo AclRepository */
  3. $aclRepo = $this->get(AclRepository::class); //In Slim 3 the container is bound to function definitions
  4. $allowed = false; // We assume that the user cannot access the route
  5. $route = '/' . ltrim($request->getUri()->getPath(), '/'); //We construct our path
  6. try { //Check here... This will pass when a route is simple and there is no route parameters
  7. $allowed = $aclRepo->isAllowedWithRoles($aclRepo->getRole(), $route);
  8. } catch (InvalidArgumentException $iae) { //This is executed in cases where there is a route parameters... /user/{id:}
  9. $fn = function (ServerRequestInterface $requestInterface, AclRepository $aclRepo) {
  10. //This will likely only work in Slim 3... This requires the determineRouteBeforeAppMiddleware => true to be set in the container
  11. $route = $requestInterface->getAttribute('route'); // Grab the route to get the pattern
  12. if (!empty($route)) {
  13. foreach ($aclRepo->getRole() as $role) {
  14. if ($aclRepo->isAllowed($role, $route->getPattern())) { // check to see fi the user can access the pattern
  15. return true; //Is allowed
  16. }
  17. }
  18. }
  19. return false;
  20. };
  21. $allowed = $fn($request, $aclRepo); // Execute the fail-safe
  22. }
  23. if ($allowed) {
  24. return $next($request, $res);
  25. } else {
  26. return $res->withStatus(401); //Is not allowed. if you need to render a template then do that.
  27. }
  28. });

White listing

You may add a URI path for white listing. The whitelisting is based upon strpos() so you may use a URI fragment to whitelist a whole class of URIs.
With this it is possible to whitelist URIs by accident.

Example:

  1. $acl = new Acl();
  2. $acl->addWhitelistItem('/api');

In this example any URI with /api will be whitelisted.

  • /api/*
  • /myexample/api/*