Python flask登录中基于角色的授权

Python flask登录中基于角色的授权,python,flask,flask-login,Python,Flask,Flask Login,我需要在现有的Flask应用程序中引入基于角色的授权。正因为如此,我不能将当前使用的flask登录包与flask user交换。然而,我必须限制“管理员”用户对某些端点的访问,而不必重建整个代码库 我想出了一个这样的装饰师: def admin_required(func): """ Modified login_required decorator to restrict access to admin group. """ @wraps(func)

我需要在现有的Flask应用程序中引入基于角色的授权。正因为如此,我不能将当前使用的flask登录包与flask user交换。然而,我必须限制“管理员”用户对某些端点的访问,而不必重建整个代码库

我想出了一个这样的装饰师:

def admin_required(func):
    """
    Modified login_required decorator to restrict access to admin group.
    """

    @wraps(func)
    def decorated_view(*args, **kwargs):
        if current_user.group != 0:        # zero means admin, one and up are other groups
            flash("You don't have permission to access this resource.", "warning")
            return redirect(url_for("main.home"))
        return func(*args, **kwargs)
    return decorated_view
我将其与原始
登录\u required
装饰器一起使用,如下所示:

@app.route("/admin-restricted"):
@login_required
@admin_required
def admin_resource():
    return "Hello admin"
一切正常,但我有两个顾虑:

  • 我的方法安全吗?我是否遗漏了潜在的安全漏洞?不幸的是,我对烧瓶内部结构的了解有限
  • 有没有更简单/安全/通灵的方法?我就是觉得不对劲

  • 处理基于角色的权限的更常见方法是使用Flask Principal

    在主应用程序中:

    from flask_principal import Principal
    
    # load the extension
    principals = Principal(app)
    
    @identity_loaded.connect_via(app)
    def on_identity_loaded(sender, identity):
        # Set the identity user object
        identity.user = current_user
        # Add the UserNeed to the identity
        if hasattr(current_user, 'employee_id'):
            identity.provides.add(UserNeed(current_user.employee_id))
    
        # Assuming the User model has a list of roles, update the
        # identity with the roles that the user provides
        if hasattr(current_user, 'position'):
            # for role in current_user.role:
            identity.provides.add(RoleNeed(str(current_user.position)))
    
       admin_permission = Permission(RoleNeed('admin'))
    
    
    然后在路线上:

    @app.route("/admin-restricted"):
    @login_required
    @admin_permission.require(http_exception=403)
    def admin_resource():
        return "Hello admin"
    

    文档:

    处理基于角色的权限的更常见方法是使用Flask Principal

    在主应用程序中:

    from flask_principal import Principal
    
    # load the extension
    principals = Principal(app)
    
    @identity_loaded.connect_via(app)
    def on_identity_loaded(sender, identity):
        # Set the identity user object
        identity.user = current_user
        # Add the UserNeed to the identity
        if hasattr(current_user, 'employee_id'):
            identity.provides.add(UserNeed(current_user.employee_id))
    
        # Assuming the User model has a list of roles, update the
        # identity with the roles that the user provides
        if hasattr(current_user, 'position'):
            # for role in current_user.role:
            identity.provides.add(RoleNeed(str(current_user.position)))
    
       admin_permission = Permission(RoleNeed('admin'))
    
    
    然后在路线上:

    @app.route("/admin-restricted"):
    @login_required
    @admin_permission.require(http_exception=403)
    def admin_resource():
        return "Hello admin"
    

    医生:

    太酷了。我已经阅读了一些文档,但只有一件事对我来说并不明显。有没有简单的方法来
    flash
    一条消息和
    redirect
    而不是抛出403?我确信有一种方法可以扩展该功能,但我承认我采取了更简单的方法,而不是使用decorator,我在view函数的第一行将其替换为:
    如果不是admin\u permission.require().can():
    然后闪烁并重定向。您可以创建一个自定义装饰器来包装Flask主体逻辑。下面是一个定制装饰器的示例,您可以在其之后建模以实现所需的效果:这很酷。我已经阅读了一些文档,但只有一件事对我来说并不明显。有没有简单的方法来
    flash
    一条消息和
    redirect
    而不是抛出403?我确信有一种方法可以扩展该功能,但我承认我采取了更简单的方法,而不是使用decorator,我在view函数的第一行将其替换为:
    如果不是admin\u permission.require().can():
    然后闪烁并重定向。您可以创建一个自定义装饰器来包装Flask主体逻辑。下面是一个自定义装饰器的示例,您可以在其之后建模以实现所需的效果: