简体   繁体   English

如何确保烧瓶管理面板具有烧瓶安全性

[英]How to secure the flask-admin panel with flask-security

I'm looking to secure Web API made using Flask and integrated with flask-admin to provide an admin interface. 我希望使用Flask保护Web API并与flask-admin集成以提供管理界面。 I searched and found that flask-admin has an admin panel at /admin and by default anyone can have access to it. 我搜索并发现flask-admin在/admin admin中有一个管理面板,默认情况下任何人都可以访问它。 It provides no authentication system and completely open (without any security) since they didn't assume what would be used to provide security. 它不提供身份验证系统并且完全打开(没有任何安全性),因为他们没有假设用于提供安全性的内容。 This API has to be used in production, so we can't have an open /admin route for everyone hitting the url. 此API必须在生产中使用,因此我们无法为每个人访问网址提供开放/admin路由。 Proper authentication is needed. 需要适当的身份验证。

In views.py I can't simply put the /admin route and provide authentication through decorator as that would be over-writing the existing route already created by flask-admin so that would cause an error. views.py我不能简单地放置/admin路由并通过装饰器提供身份验证,因为这会覆盖已由flask-admin创建的现有路由,从而导致错误。

Further research shows that there are two modules flask-admin and flask-security . 进一步的研究表明, flask-adminflask-security有两个模块。 I know that flask-admin has is_accessible method to secure it, but it doesn't provide much functionality which is provided by flask-security . 我知道flask-adminis_accessible方法来保护它,但是它没有提供很多由flask-security提供的功能。

I've not found any method there to secure the end-point /admin plus all other end-points beginning with /admin such as /admin/<something> . 我没有找到任何方法来保护端点/admin以及以/admin开头的所有其他端点,例如/admin/<something>

I'm looking specifically to do this task with flask-security. 我正在寻找专门用flask-security来完成这项任务。 If it's not possible, please suggest alternatives. 如果不可能,请提出替代方案。

PS: I know I can lock ngnix itself, but that would be the last option. PS:我知道我可以锁定ngnix本身,但这将是最后一个选择。 If I can have an authentication system through flask-security that would be good. 如果我可以通过flask-security认证系统,这将是好的。

Since this is the first result for the "flask-security secure admin" google search, and there is no out-of-the-box solution yet, I think I can contribute. 由于这是“flask-security secure admin”谷歌搜索的第一个结果,并且还没有开箱即用的解决方案,我想我可以做出贡献。

A similiar question was asked on the flask-admin project Issue List and a simple example using flask-login and mogodb is provided here . 在flask-admin项目问题列表中提出了一个类似的问题, 这里提供一个使用flask-login和mogodb的简单示例。

I made an example using SQLAchemy for a sqlite database and flask-security. 我使用SQLAchemy作为sqlite数据库和flask-security的例子。 See the sample flask app below: 请参阅下面的示例烧瓶应用:

 #!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import os.path as op
from flask import Flask, render_template, url_for, request
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy.event import listens_for
from flask.ext.security import current_user, login_required, RoleMixin, Security, SQLAlchemyUserDatastore, UserMixin
from flask_admin import Admin, AdminIndexView
from flask_admin.contrib import sqla

# Create application
app = Flask(__name__)

# Create dummy secrety key so we can use sessions
app.config['SECRET_KEY'] = '123456790'

# Create in-memory database
app.config['DATABASE_FILE'] = 'sample_db.sqlite'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + app.config['DATABASE_FILE']
app.config['SQLALCHEMY_ECHO'] = True
db = SQLAlchemy(app)

# Create directory for file fields to use
file_path = op.join(op.dirname(__file__), 'static/files')

# flask-security models

roles_users = db.Table('roles_users',
        db.Column('user_id', db.Integer(), db.ForeignKey('user.id')),
        db.Column('role_id', db.Integer(), db.ForeignKey('role.id')))

class Role(db.Model, RoleMixin):
    id = db.Column(db.Integer(), primary_key=True)
    name = db.Column(db.String(80), unique=True)
    description = db.Column(db.String(255))

class User(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(255), unique=True)
    password = db.Column(db.String(255))
    active = db.Column(db.Boolean())
    confirmed_at = db.Column(db.DateTime())
    roles = db.relationship('Role', secondary=roles_users,
                            backref=db.backref('users', lazy='dynamic'))

# Create Security
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
security = Security(app, user_datastore)

# Only needed on first execution to create first user
#@app.before_first_request
#def create_user():
#    db.create_all()
#    user_datastore.create_user(email='yourmail@mail.com', password='pass')
#    db.session.commit()

class AnyModel(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.Unicode(64))

    def __unicode__(self):
        return self.name

class MyAdminIndexView(AdminIndexView):
    def is_accessible(self):
        return current_user.is_authenticated() # This does the trick rendering the view only if the user is authenticated

# Create admin. In this block you pass your custom admin index view to your admin area 
admin = Admin(app, 'Admin Area', template_mode='bootstrap3', index_view=MyAdminIndexView())


# Add views
admin.add_view(sqla.ModelView(AnyModel, db.session)) 

# To acess the logout just type the route /logout on browser. That redirects you to the index
@login_required
@app.route('/login')
def login():
    return redirect('/admin')

@app.route('/')
def index():
    return render_template('index.html')


if __name__ == '__main__':

    # Build sample db on the fly, if one does not exist yet.
    db.create_all() 
    app.run(debug=True)

Please refer to the flask-security docs to learn how to customize the login page . 请参阅flask-security文档以了解如何自定义登录页面

Hope this helps. 希望这可以帮助。

You should check out the Flask-Security-Admin project, I think it covers pretty clearly what you are looking for. 您应该查看Flask-Security-Admin项目,我认为它非常清楚地涵盖了您正在寻找的内容。

Taken directly from the link above: 直接来自上面的链接:

  • When you first visit the app's home page, you'll be prompted to log in, thanks to Flask-Security. 当您第一次访问应用程序的主页时,由于Flask-Security,系统将提示您登录。
  • If you log in with username=someone@example.com and password=password, you'll have the "end-user" role. 如果您使用username=someone@example.com和密码=密码登录,则您将拥有“最终用户”角色。
  • If you log in with username=admin@example.com and password=password, you'll have the "admin" role. 如果您使用username=admin@example.com和密码=密码登录,则您将拥有“admin”角色。
  • Either role is permitted to access the home page. 允许任一角色访问主页。
  • Either role is permitted to access the /admin page. 允许任一角色访问/ admin页面。 However, unless you have the "admin" role, you won't see the tabs for administration of users and roles on this page. 但是,除非您具有“admin”角色,否则您将看不到用于管理此页面上的用户和角色的选项卡。
  • Only the admin role is permitted to access sub-pages of /admin page such as /admin/userview. 只允许管理员角色访问/ admin页面的子页面,例如/ admin / userview。 Otherwise, you'll get a "forbidden" response. 否则,您将收到“禁止”回复。
  • Note that, when editing a user, the names of roles are automatically populated thanks to Flask-Admin. 请注意,在编辑用户时,由于Flask-Admin,角色的名称会自动填充。
  • You can add and edit users and roles. 您可以添加和编辑用户和角色。 The resulting users will be able to log in (unless you set active=false) and, if they have the "admin" role, will be able to perform administration. 生成的用户将能够登录(除非您设置active = false),如果他们具有“admin”角色,则将能够执行管理。

The relevant code is located in main.py, and is clearly commented to explain how to replicate the process of securing the flask-admin panel using flask-security. 相关代码位于main.py中,并且明确注释以解释如何使用flask-security复制保护瓶管理面板的过程。

The most basic, relevant piece to you is the following (line 152-): 最基本的相关内容如下(第152-行):

# Prevent administration of Users unless the currently logged-in user has the "admin" role
def is_accessible(self):
    return current_user.has_role('admin')

I hope this is helpful. 我希望这是有帮助的。

I use @RamiMac's answer for all sub-views, but for the index one (by default /admin ), I use this method, re-wrap the method with an admin role required to view. 我对所有子视图使用@RamiMac的答案,但对于索引1(默认为/admin ),我使用此方法,使用查看所需的admin角色重新包装方法。

@app.before_first_request
def restrict_admin_url():
    endpoint = 'admin.index'
    url = url_for(endpoint)
    admin_index = app.view_functions.pop(endpoint)

    @app.route(url, endpoint=endpoint)
    @roles_required('admin')
    def secure_admin_index():
        return admin_index()

In my project, this goes directly after all my Flask-Admin code, which is itself in its own startup script, custom_flaskadmin.py . 在我的项目中,这直接在我的所有Flask-Admin代码之后,它本身在它自己的启动脚本custom_flaskadmin.py

Flask-Admin文档中有关于安全性的部分: http//flask-admin.readthedocs.io/en/latest/introduction/#authorization-permissions

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

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