定制 mimmi20/mezzio-generic-authorization-rbac 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

mimmi20/mezzio-generic-authorization-rbac

Composer 安装命令:

composer require mimmi20/mezzio-generic-authorization-rbac

包简介

Provides a laminas-permissions-rbac adapter for mezzio-generic-authorization.

README 文档

README

Latest Stable Version Latest Unstable Version License

Code Status

codecov Average time to resolve an issue Percentage of issues still open Mutation testing badge

This library provides a laminas-rbac adapter for mezzio-generic-authorization.

Installation

You can install the mezzio-generic-authorization-rbac library with Composer:

composer require mimmi20/mezzio-generic-authorization-rbac

Introduction

This component provides Role-Based Access Control (RBAC) authorization abstraction for the mezzio-generic-authorization library.

RBAC is based on the idea of roles. In a web application, users have an identity (e.g. username, email, etc). Each identified user then has one or more roles (e.g. admin, editor, guest). Each role has a permission to perform one or more actions (e.g. access an URL, execute specific web API calls).

In a typical RBAC system:

  • An identity has one or more roles.
  • A role requests access to a permission.
  • A permission is given to a role.

Thus, RBAC has the following model:

  • Many-to-many relationship between identities and roles.
  • Many-to-many relationship between roles and permissions.
  • Roles can have a parent role.

The first requirement for an RBAC system is identities. In our scenario, the users are generated by an authentication system, provided by mezzio-authentication. That library provides a PSR-7 request attribute named Mezzio\Authentication\UserInterface when a user is authenticated. The RBAC system uses this instance to get information about the user's identity.

Configure an RBAC system

You can configure your RBAC using a configuration file, as follows:

// config/autoload/authorization.local.php
return [
    // ...
    'mezzio-authorization-rbac' => [
        'roles' => [
            'administrator' => [],
            'editor'        => ['administrator'],
            'contributor'   => ['editor'],
        ],
        'permissions' => [
            'contributor' => [
                'admin.dashboard',
                'admin.posts',
            ],
            'editor' => [
                'admin.publish',
            ],
            'administrator' => [
                'admin.settings',
            ],
        ],
    ],
];

In the above example, we designed an RBAC system with 3 roles: administator, editor, and contributor. We defined a hierarchy of roles as follows:

  • administrator has no parent role.
  • editor has administrator as a parent. That means administrator inherits the permissions of the editor.
  • contributor has editor as a parent. That means editor inherits the permissions of contributor, and following the chain, administator inherits the permissions of contributor.

For each role, we specified an array of permissions. As you can notice, a permission is just a string; it can represent anything. In our implementation, this string represents a route name. That means the contributor role can access the routes admin.dashboard and admin.posts but cannot access the routes admin.publish (assigned to editor role) and admin.settings (assigned to administrator).

If you want to change the authorization logic for each permission, you can write your own Mimmi20\Mezzio\GenericAuthorization\AuthorizationInterface implementation. That interface defines the following method:

public function isGranted(string $role, string $resource, ?string $privilege = null, ?\Psr\Http\Message\ServerRequestInterface\ServerRequestInterface $request = null): bool;

where $role is the role, $resource is the resource, $privilege is an privilege and $request is the PSR-7 HTTP request to authorize.

This library uses the laminas/laminas-permissions-rbac library to implement the RBAC system. Privileges are not supported in this RBAC implementation. If you want to know more about the usage of this library, read the blog post Manage permissions with laminas-permissions-rbac.

Dynamic Assertion

In some cases you will need to authorize a role based on a specific HTTP request. For instance, imagine that you have an "editor" role that can add/update/delete a page in a Content Management System (CMS). We want to prevent an "editor" from modifying pages they have not created.

These types of authorization are called dynamic assertions and are implemented via the Laminas\Permissions\Rbac\AssertionInterface of laminas-permissions-rbac.

In order to use it, this package provides LaminasRbacAssertionInterface, which extends Laminas\Permissions\Rbac\AssertionInterface:

namespace Mezzio\Authorization\Rbac;

use Psr\Http\Message\ServerRequestInterface;
use Laminas\Permissions\Rbac\AssertionInterface;

interface LaminasRbacAssertionInterface extends AssertionInterface
{
    public function setRequest(ServerRequestInterface $request) : void;
}

The Laminas\Permissions\Rbac\AssertionInterface defines the following:

namespace Laminas\Permissions\Rbac;

interface AssertionInterface
{
    public function assert(Rbac $rbac, RoleInterface $role, string $permission) : bool;
}

Going back to our use case, we can build a class to manage the "editor" authorization requirements, as follows:

use Mimmi20\Mezzio\GenericAuthorization\Rbac\LaminasRbacAssertionInterface;
use App\Service\Article;
use Laminas\Permissions\Rbac\Rbac;
use Laminas\Permissions\Rbac\RoleInterface;
use Psr\Http\Message\ServerRequestInterface;

class EditorAuth implements LaminasRbacAssertionInterface
{
    public function __construct(Article $article)
    {
        $this->article = $article;
    }

    public function setRequest(ServerRequestInterface $request): void
    {
        $this->request = $request;
    }

    public function assert(Rbac $rbac, RoleInterface $role, string $permission): bool
    {
        $user = $this->request->getAttribute(UserInterface::class, false);
        return $this->article->isUserOwner($user->getIdentity(), $this->request);
    }
}

Where Article is a class that checks if the identified user is the owner of the article referenced in the HTTP request.

If you manage articles using a SQL database, the implementation of isUserOwner() might look like the following:

public function isUserOwner(string $identity, ServerRequestInterface $request): bool
{
    // get the article {article_id} attribute specified in the route
    $url = $request->getAttribute('article_id', false);
    if (! $url) {
        return false;
    }
    $sth = $this->pdo->prepare(
        'SELECT * FROM article WHERE url = :url AND owner = :identity'
    );
    $sth->bindParam(':url', $url);
    $sth->bindParam(':identity', $identity);
    if (! $sth->execute()) {
        return false;
    }
    $row = $sth->fetch();
    return ! empty($row);
}

To pass the Article dependency to your assertion, you can use a Factory class that generates the EditorAuth class instance, as follows:

use App\Service\Article;

class EditorAuthFactory
{
    public function __invoke(ContainerInterface $container) : EditorAuth
    {
        return new EditorAuth(
            $container->get(Article::class)
        );
    }
}

And configure the service container to use EditorAuthFactory to point to EditorAuth, using the following configuration:

return [    
    'dependencies' => [
        'factories' => [
            // ...
            EditorAuth::class => EditorAuthFactory::class
        ]
    ]
];

License

This package is licensed using the MIT License.

Please have a look at LICENSE.md.

mimmi20/mezzio-generic-authorization-rbac 适用场景与选型建议

mimmi20/mezzio-generic-authorization-rbac 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 14 次下载、GitHub Stars 达 1, 最近一次更新时间为 2020 年 10 月 22 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「authorization」 「middleware」 「rbac」 「psr-7」 「psr-15」 「mezzio」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 mimmi20/mezzio-generic-authorization-rbac 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 mimmi20/mezzio-generic-authorization-rbac 我们能提供哪些服务?
定制开发 / 二次开发

基于 mimmi20/mezzio-generic-authorization-rbac 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 14
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 1
  • 点击次数: 11
  • 依赖项目数: 0
  • 推荐数: 1

GitHub 信息

  • Stars: 1
  • Watchers: 1
  • Forks: 1
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2020-10-22