定制 typo3/access-control 二次开发

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

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

typo3/access-control

Composer 安装命令:

composer require typo3/access-control

包简介

TYPO3 Access Control Component.

README 文档

README

Build Coverage Code Quality

Installation

Use composer to install this extension in your project:

composer require typo3/access-control

Concepts

Access rights are granted to users through the use of policies. The underlying model is known as attribute-based access control (ABAC). It makes use of boolean expressions which decide whether an access request is granted or not. Such a request typically contains the resource, action, subject and environment attributes. This extension implements a lightweight policy language and evaluation framework based on Jiang, Hao & Bouabdallah, Ahmed (2017).

The policy structure consists of policy sets, policies and rules. A policy set is a set of policies which in turn has a set of rules. Because not all policies are relevant to a given request every element includes the notion of a target. It determines whether a policy is applicable to a request by setting constraints on attributes using boolean expressions.

A policy is applicable if the access request satisfies the target. If so, its childrend are evaluated and the results returned by those children are combined using a combining algorithm. Otherwise, the policy is skipped without further examining its children and returns a not applicable decision.

The rule is the fundamental unit that can generate a conclusive decision. The condition of a rule is a more complex boolean expression that refines the applicability beyond the predicates specified by its target, and is optional. If a request satisfies both the target and condition of a rule, then the rule is applicable to the request and its effect is returned as its decision. Otherwise, not applicable is returned.

Each rule, policy or policy set has an unique identifier and obligations which represent the operations to perform after granting or denying an access request.

Attributes

A request typically contains the following attributes:

Attribute Description
resource Is an entity to be protected from unauthorized use. The resource is directly provided by the access request. See also TYPO3\AccessControl\Attribute\ResourceAttribute.
subject Represents the entity requesting to perform an operation upon the resource. It is provided indirectly through the given context of the policy decision point and can not modifed or set by the access request directly. See also TYPO3\AccessControl\Attribute\SubjectAttribute.
action The operations to be performed on the resource. Like the resource it is also provided by the access request. See also TYPO3\AccessControl\Attribute\ActionAttribute.

To define your own attributes, you must derive them from one of the corresponding classes:

namespace App\Security\AccessControl\Attribute;

use TYPO3\AccessControl\Attribute\PrincipalAttribute;

class RoleAttribute extends PrincipalAttribute
{
  public function __construct(string $identifier)
  {
    parent::__construct($identifier);
  }
}

Expressions

Expressions are used to decied whether a policy is applicable to a request or not. Therefore a so called expression resolver has to be implemented. For example, by using the expression language component:

namespace App\Security\AccessControl\Expression;

use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
use TYPO3\AccessControl\Expression\ResolverInterface;

class ExpressionLanguageResolver implements ResolverInterface
{
  private $expressionLanguage;

  public function __construct()
  {
    $this->expressionLanguage = new ExpressionLanguage();
    // register a custom function `hasAuthority`
    $this->expressionLanguage->register(
      'hasAuthority', function () {
        // not implemented, we only use the evaluator
      },
      function ($variables, ...$arguments) {
        if (count($arguments) == 1) {
          // checks if the subject has the given principal
          return isset($variables['subject']->principals[$arguments[0]]);
        }
        return false;
      }
    );
  }

  public function validate(string $expression): void
  {
    // only allow the attributes `subject`, `resource` and `action`
    $this->expressionLanguage->parse($expression, ['subject', 'resource', 'action']);
  }

  public function evaluate(string $expression, array $attributes): bool
  {
    return $this->expressionLanguage->evaluate($expression, $attributes);
  }
}

Policies

Policies can be defined declaratively. For example, by using YAML and the policy factory:

---
description: 'Root policy set.'
algorithm: highestPriority
policies:
  Admin:
    target: 'hasAuthority("typo3:security:principal:admin")'
    description: 'Administrator policy'
    priority: 100
    rules:
      -
        effect: permit
  Default:
    description: 'Deny everything per default.'
    rules:
      -
        obligation:
          deny:
            Feedback: ['Access denied.']
use App\Security\AccessControl\Expression\ExpressionLanguageResolver;
use Symfony\Component\Yaml\Parser;
use TYPO3\AccessControl\Policy\PolicyFactory;

$resolver = new ExpressionLanguageResolver();
$factory = new PolicyFactory();
$parser = new Parser();

$policy = $factory->build(
  $parser->parseFile('/path/to/policies.yaml'),
  $resolver
);

A policy set is a set of policy sets and policies. It has the following configuration fields:

Field Description
description Optional description of the policy set.
target Optional boolean expression indicating the resource, action, subject and environment attributes to which the policy set is applied. Default is true.
alogrithm Optional name of a combining algorithm to compute the final decision according to the results returned by its child policies, either denyOverride, permitOverride, firstApplicable or highestPriority. Default is firstApplicable.
priority Optional number indicating the weight of the policy set when its decision conflicts with other policies under the highestPriority algorithm. Default is 1.
obligation Optional actions to take in case a particular conclusive decision (permit or deny) is reached.
policies Required set of child policies (policy sets and policies).

With configuration fields similar to a policy set a policy is a set of rules:

Field Description
description Optional description of the policy.
target Optional boolean expression indicating the resource, action, subject and environment attributes to which the policy is applied. Default is true.
alogrithm Optional name of a combining algorithm to compute the final decision according to the results returned by its child rules, either denyOverride, permitOverride, firstApplicable or highestPriority. Default is firstApplicable.
priority Optional number indicating the weight of the policy when its decision conflicts with other policies under the highestPriority algorithm. Default is 1.
obligation Optional actions to take in case a particular conclusive decision (permit or deny) is reached.
rules Required set of child rules.

Unlike a policy set or a policy, a rule does not contain any leaf nodes:

Field Description
target Optional boolean expression indicating the resource, action, subject and environment attributes to which the policy is applied. Default is true.
effect Optional returned decision when the rule is applied, either permit or deny. Default is deny.
condition Optional boolean expression that specifies the condition for applying the rule. In comparison to a target, a condition is typically more complex. If either the target or the condition is not satisfied, a not applicable would be taken as the result instead of the specified effect. Default is true.
priority Optional number indicating the weight of the rule when its decision conflicts with other rules under the highestPriority algorithm. Default is 1.
obligation Optional actions to take in case a particular conclusive decision (permit or deny) is reached.

Policies may conflict and produce different decisions for the same request. To resolve this four kinds of combining algorithms are provided. Each algorithm represents a different way for combining multiple local decisions into a single global decision:

Algorithm Description
permitOverrides Returns permit if any decision evaluates to permit and returns deny if all decisions evaluate to deny.
denyOverrides Returns deny if any decision evaluates to deny and returns permit if all decisions evaluate to permit.
firstApplicable Returns the first decision that evaluates to either of permit or deny.
highestPriority Returns the highest priority decision that evaluates to either of permit or deny. If there are multiple equally highest priority decisions that conflict, then deny overrides algorithm would be applied among those highest priority decisions.

Please note that for all of these combining algorithms, not applicable is returned if not any of the children is applicable.

There is also formal description of the schema for the policy language which can be found here.

Authorisation

To perform an access request the policy decision point has to be used. It evaluates all policies and returns a decision either of permit, deny or not applicable:

use App\Security\AccessControl\Attribute\ActionAttribute;
use App\Security\AccessControl\Attribute\ResourceAttribute;
use Symfony\Component\EventDispatcher\EventDispatcher;
use TYPO3\AccessControl\Policy\PolicyDecisionPoint;
use TYPO3\AccessControl\Policy\PolicyInformationPoint;

$dispatcher = new EventDispatcher();

// creeates an policy information point
$policyInformationPoint = new PolicyInformationPoint(
  $dispatcher
);

// creates a policy decision point
$policyDecisionPoint = new PolicyDecisionPoint(
  $dispatcher,
  $policy,
  $policyInformationPoint
);

// perform an authorization request
$policyDecision = $policyDecisionPoint->authorize(
  [
    // concrete resource to access
    'resource' => new ResourceAttribute('identifier'),
    // concrete action on resource
    'action' => new ActionAttribute()
  ]
);

if (!$policyDecision->isApplicable()) {
  // access request is not applicable
}

// process determining policy rule
$determinigRule = $policyDecision->getRule();

foreach ($policyDecision->getObligations() as $obligation) {
  // process obligations
}

if ($policyDecision->getValue() === PolicyDecision::PERMIT)
  // access is granted
}

// access is denied otherwise

To receive all operations which should be performed after denying or granting an access request the event \TYPO3\AccessControl\Event\PolicyDecisionEvent has to be used:

namespace App\Security\AccessControl\EventListener;

use TYPO3\AccessControl\Event\PolicyDecisionEvent;

class PolicyDecisionListener
{
    public function __invoke(PolicyDecisionEvent $event)
    {
        // ...
    }
}

To provide additional data for an attribute before an access request the event \TYPO3\AccessControl\Event\AttributeRetrievalEvent can be used:

namespace App\Security\AccessControl\EventListener;

use TYPO3\AccessControl\Event\AttributeRetrievalEvent;

class AttributeRetrievalListener
{
    public function __invoke(AttributeRetrievalEvent $event)
    {
        // ...
    }
}

To provide principals for the subject attribute the separate event \TYPO3\AccessControl\Event\SubjectRetrievalEvent has to be used:

namespace App\Security\AccessControl\EventListener;

use TYPO3\AccessControl\Attribute\PrincipalAttribute;
use TYPO3\AccessControl\Event\SubjectRetrievalEvent;

class SubjectRetrievalListener
{
    public function __invoke(SubjectRetrievalEvent $event)
    {
        // Adds administrator principal
        $event->addPrincipal(new PrincipalAttribute('administrator'));
    }
}

Design Principals

Whenever possible the authorization logic should be part of a policy. Thus it's auditable and changeable. For reasons of performance or complexity it might be not possible. Then it's recommended to extend the expression language with a custom function if possible.

Development

Development for this extension is happening as part of the TYPO3 persistence initiative.

typo3/access-control 适用场景与选型建议

typo3/access-control 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 985 次下载、GitHub Stars 达 5, 最近一次更新时间为 2019 年 12 月 02 日, 在 PHP 生态内属于活跃度较高的组件。

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

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

围绕 typo3/access-control 我们能提供哪些服务?
定制开发 / 二次开发

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

BUG 修复 & 性能优化

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

项目外包 & 长期维护

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

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

统计信息

  • 总下载量: 985
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 5
  • 点击次数: 4
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 5
  • Watchers: 4
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2019-12-02