编写CherryPy装饰器以进行授权

时间:2010-07-21 19:08:01

标签: python permissions authorization decorator cherrypy

我有一个讨厌的应用程序,在某些视图中我想开始只允许某些用户查看它们,并将其他人发送到授权所需页面。

有没有办法可以用自定义装饰器做到这一点?我认为这将是最优雅的选择。

以下是我想要做的基本示例:

class MyApp:
    @authorization_required
    def view_page1(self,appID):
        ... do some stuff ...
        return html

def authorization_required(func):
    #what do I put here?

当被调用为decorator时,authorization_required函数也可以接受allow_group1,allow_group2等参数吗?或者我是否需要为每个组分别设置一个装饰器?

2 个答案:

答案 0 :(得分:14)

你真的不想为CherryPy编写自定义装饰器。相反,您想要编写一个新工具:

def myauth(allowed_groups=None, debug=False):
    # Do your auth here...
    authlib.auth(...)
cherrypy.tools.myauth = cherrypy.Tool("on_start_resource", myauth)

有关更多讨论,请参阅http://docs.cherrypy.org/en/latest/extend.html#tools。这比编写自定义装饰器有几个好处:

  1. 你可以从工具@cherrypy.tools.myauth(allowed_groups=['me'])中免费获得装饰器,它已经知道如何在同一个函数上破解cherrypy.exposed。
  2. 您可以为每个处理程序(使用装饰器),每个控制器树(通过_cp_config)或每个URI树(在配置文件或dicts中)应用工具。您甚至可以混合它们并通过装饰器提供基本功能,然后覆盖它们在配置文件中的行为。
  3. 如果配置文件关闭了您的功能,您不需要支付调用装饰器功能的性能损失,只是为了查看它是否已关闭。
  4. 你会记得像所有内置工具一样添加'debug'arg。 ;)
  5. 通过选择不同的“点”,您的功能可以比自定义装饰器更早(或更晚,如果这是你需要的)运行。
  6. 如果需要,您的功能可以在多个挂钩点运行。

答案 1 :(得分:4)

好的,在这种情况下你的装饰师看起来像这样:

# without any parameters
def authentication_required(f):
    @functools.wraps(f)
    def _authentication_required(*args, **kwargs):
        # Do you login stuff here
        return f(*args, **kwargs)
    return _authentication_required

# With parameters
def authentication_required(*allowed_groups):
    def _authentication_required(f):
        @functools.wraps(f)
        def __authentication_required(*args, **kwargs):
            # Do you login stuff here
            return f(*args, **kwargs)
        return __authentication_required
    return _authentication_required