遇到“细粒度”金字塔ACL问题

时间:2021-10-09 03:18:12

I have a 5 types of users:

我有5种类型的用户:

  1. Admin     (permissions ALL)
  2. 管理员(权限ALL)
  3. Creator   (permissions "v", "a", "m", "c")
  4. 创作者(权限“v”,“a”,“m”,“c”)
  5. Manager (permissions "v", "a", "m")
  6. 经理(权限“v”,“a”,“m”)
  7. Analyst   (permissions "v", "a")
  8. 分析师(权限“v”,“a”)
  9. Viewer    (permissions "v")
  10. 查看者(权限“v”)

This is a hierarchical setup where each user has the permissions of each preceding user. To set this up in my project, I can easily write:

这是一种分层设置,其中每个用户都拥有每个在先用户的权限。要在我的项目中进行设置,我可以轻松地写出:

class RootFactory(object):

    __acl__ = [ 
        (Allow, '__ADMIN__', ALL_PERMISSIONS),
        (Allow, 'creator',  ('VIEWER', 'ANALYST', 'MANAGER', 'CREATOR')),
        (Allow, 'manager',  ('VIEWER', 'ANALYST', 'MANAGER')),
        (Allow, 'analyst',  ('VIEWER', 'ANALYST')),
        (Allow, 'viewer',   ('VIEWER')),
        (Allow, Everyone, NO_PERMISSION_REQUIRED) 
    ]

    def __init__(self, request):
        self.request = request

Then, in my views.py, for example, I do:

然后,在我的views.py中,例如,我做:

@view_config(route_name='mgmt_handler', renderer='manage.jinja2', permission='MANAGER')
def mgmt_handler(request):
    pass  # do stuff

This works nicely for most instances. However, I am not sure of how to best accomplish the following:

这适用于大多数情况。但是,我不确定如何最好地完成以下任务:

  • How do I make this access control more "fine-grained" by allowing user1, a viewer, to have certain higher permissions on an as needed basis? Does this fall under the realm of "object-level" security? For the most part, the global root factory will suffice, but how can I accommodate those cases where a low-tier user is granted a higher permission, or when a high-tier user is denied a lower permission?

    如何允许user1(一个查看者)根据需要拥有某些更高的权限,从而使这种访问控制更加“细粒度”?这是否属于“对象级”安全领域?在大多数情况下,全局根工厂就足够了,但是如何适应低级别用户被授予更高权限的情况,或者高级用户被拒绝较低权限的情况?

  • Is there a way to conveniently determine the principles of a particular user so that in my view I can say something to the effect of: if user.principle in list_of_permissions: do something...? Or, is this simply another query from the database, where the user's groups are stored?

    有没有办法方便地确定特定用户的原则,以便在我的视图中我可以说一些效果:如果list_of_permissions中的user.principle:做某事......?或者,这只是来自数据库的另一个查询,其中存储了用户的组?

Case and point, my goal is to have a flexible, hierarchical permission system. What is the most effective way to do this? The tutorials I've read only address more simple, global policies (which I do understand.) Part of my problem is how to a comprehensive understanding of object/instance-level security.

案例和观点,我的目标是拥有灵活的分层权限系统。这样做最有效的方法是什么?我读过的教程只涉及更简单的全局策略(我明白了)。我的部分问题是如何全面理解对象/实例级安全性。

Thanks for the help.

谢谢您的帮助。

2 个解决方案

#1


3  

I'm not sure I clearly get what you want to achieve. As I understood, you have a handful of user groups with common permissions for each object in the system, and going to tune access to a particular object for a particular user. For example, owner of an object has all permissions for the object regardless of owner's user group.

我不确定我是否清楚地得到了你想要达到的目标。据我所知,您有一些用户组对系统中的每个对象具有共同权限,并且将调整对特定用户的特定对象的访问权限。例如,对象的所有者拥有该对象的所有权限,而不管所有者的用户组如何。

Firstly, you should use a hierarchy of location-aware resources. In this way you can keep default permissions in the root resource and tune them in the child one:

首先,您应该使用位置感知资源的层次结构。通过这种方式,您可以保留根资源中的默认权限并在子资源中调整它们:

class RootFactory(object):

    __name__ = ''
    __parent__ = None
    __acl__ = [ 
        (Allow, '__ADMIN__', ALL_PERMISSIONS),
        (Allow, 'creator',  ('VIEWER', 'ANALYST', 'MANAGER', 'CREATOR')),
        (Allow, 'manager',  ('VIEWER', 'ANALYST', 'MANAGER')),
        (Allow, 'analyst',  ('VIEWER', 'ANALYST')),
        (Allow, 'viewer',   ('VIEWER')),
        # (Allow, Everyone, NO_PERMISSION_REQUIRED) 
        # It seems, here you want to deny access for all other users, 
        # so you should use this:
        # (Deny, Everyone, ALL_PERMISSIONS)
        # or simply:
        DENY_ALL
    ]

    def __init__(self, request):
        self.request = request

    def __getitem__(self, name):
        return ChildObject(name, self)

Then in the child object constructor, you can add a special permissions for this particular object:

然后在子对象构造函数中,您可以为此特定对象添加特殊权限:

class ChileObject(object):

    def __init__(self, request, name, parent):
        self.__parent__ = parent
        self.__name__ = name
        # Do some stuff, for example loading object from DB 
        # and populate other attributes of the object.
        # Then add permission for the object's owner
        self.__acl__ = [(Allow, self.owner_id, ALL_PERMISSIONS)]

The result ACL will be merged version of root's ACL and child's one, i.e:

结果ACL将是root的ACL和子的ACL的合并版本,即:

[ 
    (Allow, self.owner_id, ALL_PERMISSIONS),
    (Allow, '__ADMIN__', ALL_PERMISSIONS),
    (Allow, 'creator',  ('VIEWER', 'ANALYST', 'MANAGER', 'CREATOR')),
    (Allow, 'manager',  ('VIEWER', 'ANALYST', 'MANAGER')),
    (Allow, 'analyst',  ('VIEWER', 'ANALYST')),
    (Allow, 'viewer',   ('VIEWER')),
    DENY_ALL 
]

As for your second question, you can find a useful functions for checking permissions in the pyramid.security module.

至于第二个问题,您可以找到一个有用的函数来检查pyramid.security模块中的权限。

#2


0  

Most permission systems have both users and groups. If you added groups to your situation, you could create a separate group that adds the permissions you want, and then add the users you want to have these permissions. You can add and remove a user from a group as needed.

大多数权限系统都有用户和组。如果您根据具体情况添加了组,则可以创建一个单独的组来添加所需的权限,然后添加要拥有这些权限的用户。您可以根据需要在组中添加和删除用户。

You could also build in exceptions to resources. For example you could add a list of users to a resource who are allowed to modify it regardless of what other permissions they might have.

您还可以构建资源的例外。例如,您可以向允许修改它的资源添加用户列表,而不管它们可能具有哪些其他权限。

#1


3  

I'm not sure I clearly get what you want to achieve. As I understood, you have a handful of user groups with common permissions for each object in the system, and going to tune access to a particular object for a particular user. For example, owner of an object has all permissions for the object regardless of owner's user group.

我不确定我是否清楚地得到了你想要达到的目标。据我所知,您有一些用户组对系统中的每个对象具有共同权限,并且将调整对特定用户的特定对象的访问权限。例如,对象的所有者拥有该对象的所有权限,而不管所有者的用户组如何。

Firstly, you should use a hierarchy of location-aware resources. In this way you can keep default permissions in the root resource and tune them in the child one:

首先,您应该使用位置感知资源的层次结构。通过这种方式,您可以保留根资源中的默认权限并在子资源中调整它们:

class RootFactory(object):

    __name__ = ''
    __parent__ = None
    __acl__ = [ 
        (Allow, '__ADMIN__', ALL_PERMISSIONS),
        (Allow, 'creator',  ('VIEWER', 'ANALYST', 'MANAGER', 'CREATOR')),
        (Allow, 'manager',  ('VIEWER', 'ANALYST', 'MANAGER')),
        (Allow, 'analyst',  ('VIEWER', 'ANALYST')),
        (Allow, 'viewer',   ('VIEWER')),
        # (Allow, Everyone, NO_PERMISSION_REQUIRED) 
        # It seems, here you want to deny access for all other users, 
        # so you should use this:
        # (Deny, Everyone, ALL_PERMISSIONS)
        # or simply:
        DENY_ALL
    ]

    def __init__(self, request):
        self.request = request

    def __getitem__(self, name):
        return ChildObject(name, self)

Then in the child object constructor, you can add a special permissions for this particular object:

然后在子对象构造函数中,您可以为此特定对象添加特殊权限:

class ChileObject(object):

    def __init__(self, request, name, parent):
        self.__parent__ = parent
        self.__name__ = name
        # Do some stuff, for example loading object from DB 
        # and populate other attributes of the object.
        # Then add permission for the object's owner
        self.__acl__ = [(Allow, self.owner_id, ALL_PERMISSIONS)]

The result ACL will be merged version of root's ACL and child's one, i.e:

结果ACL将是root的ACL和子的ACL的合并版本,即:

[ 
    (Allow, self.owner_id, ALL_PERMISSIONS),
    (Allow, '__ADMIN__', ALL_PERMISSIONS),
    (Allow, 'creator',  ('VIEWER', 'ANALYST', 'MANAGER', 'CREATOR')),
    (Allow, 'manager',  ('VIEWER', 'ANALYST', 'MANAGER')),
    (Allow, 'analyst',  ('VIEWER', 'ANALYST')),
    (Allow, 'viewer',   ('VIEWER')),
    DENY_ALL 
]

As for your second question, you can find a useful functions for checking permissions in the pyramid.security module.

至于第二个问题,您可以找到一个有用的函数来检查pyramid.security模块中的权限。

#2


0  

Most permission systems have both users and groups. If you added groups to your situation, you could create a separate group that adds the permissions you want, and then add the users you want to have these permissions. You can add and remove a user from a group as needed.

大多数权限系统都有用户和组。如果您根据具体情况添加了组,则可以创建一个单独的组来添加所需的权限,然后添加要拥有这些权限的用户。您可以根据需要在组中添加和删除用户。

You could also build in exceptions to resources. For example you could add a list of users to a resource who are allowed to modify it regardless of what other permissions they might have.

您还可以构建资源的例外。例如,您可以向允许修改它的资源添加用户列表,而不管它们可能具有哪些其他权限。