实体管理服务,我是否使事情过于复杂


Services for entity management, am I overcomplicating things?

我目前正在尝试使用Symfony(2.3版(创建自己的授权系统。我不确定我是否把事情复杂化了,我对Symfony和SOA很陌生。我正在创建自己的授权系统,因为我需要根据当前用户、其角色和当前客户(当前用户可以更改客户(及其产品来限制权限。

我目前拥有的,我认为可能太复杂了,如下:

对于每个实体,我有一个仅用于读取操作的存储库:

MyBundle/Entities/
                  Customer.php/CustomerRepository.php
                  Product.php/ProductRepository.php
                  ...

抽象存储库的使用以及创建/更新/删除的处理。我有一个使用存储库的每个实体的管理器类(代理存储库和使用不同存储库的组合(。

MyBundle/Manager/
                  CustomerManager.php
                  ProductManager.php
                  ...

然后我有我的类,这些课程根据当前用户,其角色和当前选定的客户及其产品获得授权。他们使用管理器来加载所有 ACL 数据。

MyBundle/Authorization/
                       AuthCustomers.php //Allowed customers to which user is assigned
                       AuthRights.php    //Rights according to user and customer

服务如下所示:

auth.manager.product:
    class: MyBundle'Manager'ProductManager
    arguments: ["@doctrine.odm.mongodb.document_manager"]
auth.manager.customer:
    class: MyBundle'Manager'CustomerManager
    arguments: ["@doctrine.odm.mongodb.document_manager"]
auth.authorization.authorization_rights_factory:
    class: MyBundle'Authorization'AuthorizationRightsFactory
    arguments: ["@auth.manager.role", "@auth.manager.customer"]
auth.authorization.authorization_customers_factory:
    class: MyBundle'Authorization'AuthorizationCustomersFactory
    arguments: ["@auth.manager.group", "@auth.manager.customer"]

到目前为止,我实际上认为这是可以的。但是我现在需要的和我担心的是,当对这些实体中的任何一个执行某些操作时,如果允许我这样做,我实际上需要检查我的AuthorizationXXX服务。因此,Authorization类依赖于Manager,反之亦然。
为了抽象它(为了防止无限引用,我可以在控制器和命令脚本中重用它(,我现在将创建另一个服务,在其中注入AuthorizationManager服务并执行这些检查。所以我实际上会有另一位经理来服务我。

最后,我将拥有 7 个实体,具有 7 个存储库和 7 个管理器 + 一些授权类 + 7 个服务来组合管理器和授权类。

现在的问题是,这是正确的方法吗?我真的觉得我把事情复杂化了。欢迎任何更简单的建议:)

选民似乎符合您的需求,请查看文档:http://symfony.com/doc/current/components/security/authorization.html#voters

您可以创建一个 Voter,它将当前用户、他的角色和当前客户作为参数,如果您的业务规则得到遵守,则返回 true,如果不符合,则返回 false。

最后,

我现在只保留了结构,只是稍微改变了层的含义。我现在拥有并感到舒服的是:

对于只读操作Repositories,知道其他存储库(在这里,我一开始就过头了,希望让存储库彼此不知道(。

Manager处理实体的持久性并代理到Repositories的读取操作。他们不在乎Authorization.

Authorization只处理我的授权事务的服务,因此它们可以在任何地方重用,而无需执行Symfony特定的事情。

Model服务结合了ManagerAuthorization以及一般的所有部门。实际上,Symfony控制器只会调用模型服务的方法。但是有了这个,我也可以将其重用于命令行脚本等。

我仍然有很多课程,但他们现在分开得很好,只做他们的东西,可以很容易地更换。

总的来说,我还详细查看了FOSUserBundle以获得一些灵感。我认为他们总体上解决得很好。