简体   繁体   English

烧瓶登录中基于角色的授权

[英]Role based authorization in flask-login

I need to introduce role-based authorization in existing Flask application.我需要在现有的 Flask 应用程序中引入基于角色的授权。 Because of that I can't just swap currently used flask-login package with flask-user for example.因此,例如,我不能仅将当前使用的烧瓶登录 package 与烧瓶用户交换。 Nevertheless I have to restrict access to some endpoints to "admin" users without rebuilding entire code base.尽管如此,我必须将对某些端点的访问限制为“管理员”用户,而无需重建整个代码库。

I came up with a decorator like this:我想出了一个这样的装饰器:

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

I use it with original login_required decorator like so:我将它与原始login_required装饰器一起使用,如下所示:

@app.route("/admin-restricted"):
@login_required
@admin_required
def admin_resource():
    return "Hello admin"

Everything works as expected BUT I have two concerns:一切都按预期工作,但我有两个担忧:

  1. Is my method safe?我的方法安全吗? Have I missed something which is potential security flaw?我是否错过了一些潜在的安全漏洞? Unfortunately I have limited knowledge about Flask internals.不幸的是,我对 Flask 内部结构了解有限。
  2. Is there more simple/safe/pythonic way to do that?有没有更简单/安全/pythonic的方法来做到这一点? It just doesn't feel right to me.我只是觉得不对劲。

The more common method of dealing with role based permissions is to use Flask Principal.处理基于角色的权限的更常见方法是使用 Flask Principal。

In the main app:在主应用程序中:

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'))

And then in the route:然后在路线中:

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

Docs: https://pythonhosted.org/Flask-Principal/文档: https://pythonhosted.org/Flask-Principal/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM