geggleto/psr7-acl

PSR-7 Zend ACL

1.3.0 2016-03-21 17:03 UTC

This package is auto-updated.

Last update: 2024-09-18 02:39:13 UTC


README

Build Status

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/*