geggleto / psr7-acl
PSR-7 Zend ACL
1.3.0
2016-03-21 17:03 UTC
Requires
Requires (Dev)
- phpunit/phpunit: ^5.1
README
geggleto-acl
提供基于 Zend/Permissions/Acl 库的 ACL 仓库和中间件,遵循 PSR-7 规范
工作原理
- 资源是端点
- 角色是一组资源
- 您可以允许或拒绝这些角色。
每次请求都会将用户的角色加载到 AclRepo 中。我建议将它们加载到会话变量中,而不是每次都从存储中获取(根据使用情况而定)。
然后检查当前路由,并与中间件中的可访问资源列表进行比较。如果用户不允许,则返回 401。如果用户允许,则应用程序可以继续。
默认情况下,401 不提供消息正文,如果您需要渲染页面,则需要编写自己的中间件。
使用示例
//Define or Pull your ACL's into the following format /* $config = [ "resources" => ["/", "/no", "/yes"], "roles" => ["guest", "user1", "user2"], "assignments" => [ "allow" => [ "guest" => ["/"], "user1" => ["/", "/no"], "user2" => ["/", "/yes"] ], "deny" => [ "guest" => ["/no", "/yes"], "user1" => ["/yes"], "user2" => ["/no"] ] ] ]; */ //In Slim v3 $app->add(\Geggleto\Acl\AclRepository(["guest"], //This should be in a nice php file by itself for easy inclusion... include '/path/to/acl/definition.php' [ "resources" => ["/", "/no", "/yes"], "roles" => ["guest", "user1", "user2"], "assignments" => [ "allow" => [ "guest" => ["/"], "user1" => ["/", "/no"], "user2" => ["/", "/yes"] ], "deny" => [ "guest" => ["/no", "/yes"], "user1" => ["/yes"], "user2" => ["/no"] ] ] ]));
动态路由
在资源更改的情况下,可以通过设置带有路由模式的资源来正确匹配。默认情况下,系统将检查 $request 的 'route' 属性,该对象应该返回路由模式 ->getPatter(); 如果您已启用 'determineRouteBeforeAppMiddleware' => true 选项,则 Slim 3 路由将直接工作。
示例配置
return [ "resources" => ["/", "/login", "/grid", "/404", "/logout", "/roles", "/roles/{pein}"], "roles" => ["guest", "grid", "roles"], "assignments" => [ "allow" => [ "guest" => ["/", "/404", "/login"], "grid" => [ '/grid', '/logout' ], "roles" => ['/roles', '/roles/{pein}'] ], "deny" => [] ] ];
如果您不满足使用,可以通过设置自己的 setHandler(callable)
来覆盖默认处理程序。
中间件
您可以直接使用包含此代码块的 repo 类...或者修改此代码块以适应您的需求。
$app->add(function (Request $request, Response $res, $next) { /** @var $aclRepo AclRepository */ $aclRepo = $this->get(AclRepository::class); //In Slim 3 the container is bound to function definitions $allowed = false; // We assume that the user cannot access the route $route = '/' . ltrim($request->getUri()->getPath(), '/'); //We construct our path try { //Check here... This will pass when a route is simple and there is no route parameters $allowed = $aclRepo->isAllowedWithRoles($aclRepo->getRole(), $route); } catch (InvalidArgumentException $iae) { //This is executed in cases where there is a route parameters... /user/{id:} $fn = function (ServerRequestInterface $requestInterface, AclRepository $aclRepo) { //This will likely only work in Slim 3... This requires the determineRouteBeforeAppMiddleware => true to be set in the container $route = $requestInterface->getAttribute('route'); // Grab the route to get the pattern if (!empty($route)) { foreach ($aclRepo->getRole() as $role) { if ($aclRepo->isAllowed($role, $route->getPattern())) { // check to see fi the user can access the pattern return true; //Is allowed } } } return false; }; $allowed = $fn($request, $aclRepo); // Execute the fail-safe } if ($allowed) { return $next($request, $res); } else { return $res->withStatus(401); //Is not allowed. if you need to render a template then do that. } });
白名单
您可以添加 URI 路径以进行白名单设置。白名单基于 strpos()
,因此您可以使用 URI 片段来白名单一类 URI。这样,您可能会意外地白名单 URI。
示例
$acl = new Acl(); $acl->addWhitelistItem('/api');
在此示例中,任何带有 /api
的 URI 都将被白名单。
/api/*
/myexample/api/*