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

San*_*ana 19 security authentication flask flask-security flask-admin

我希望使用Flask保护Web API并与之集成flask-admin以提供管理界面.我搜索并发现flask-admin有一个管理面板,/admin默认情况下任何人都可以访问它.它不提供身份验证系统并且完全打开(没有任何安全性),因为他们没有假设用于提供安全性的内容.此API必须在生产中使用,因此我们无法/admin为每个人访问网址提供开放路径.需要适当的身份验证.

views.py我不能简单地放置/admin路由并通过装饰器提供身份验证,因为这将覆盖已经创建的现有路由flask-admin,从而导致错误.

进一步的研究表明,有两个模块flask-adminflask-security.我知道flask-adminis_accessible保护它的方法,但它没有提供很多功能flask-security.

我没有找到任何方法来确保终点/admin加上所有其他终点,/admin例如/admin/<something>.

我正在寻找专门用flask-security来完成这项任务.如果不可能,请提出替代方案.

PS:我知道我可以锁定ngnix自己,但那将是最后一个选择.如果我可以拥有一个认证系统,flask-security那将是好事.

gui*_*ama 13

由于这是"flask-security secure admin"谷歌搜索的第一个结果,并且还没有开箱即用的解决方案,我想我可以做出贡献.

在flask-admin项目问题列表中提出了一个类似的问题,这里提供一个使用flask-login和mogodb的简单示例.

我使用SQLAchemy作为sqlite数据库和flask-security的例子.请参阅下面的示例烧瓶应用:

 #!/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)
Run Code Online (Sandbox Code Playgroud)

请参阅flask-security文档以了解如何自定义登录页面.

希望这可以帮助.


小智 9

您应该查看Flask-Security-Admin项目,我认为它非常清楚地涵盖了您正在寻找的内容.

直接来自上面的链接:

  • 当您第一次访问应用程序的主页时,由于Flask-Security,系统将提示您登录.
  • 如果您使用username=someone@example.com和密码=密码登录,则您将拥有"最终用户"角色.
  • 如果您使用username=admin@example.com和密码=密码登录,则您将拥有"admin"角色.
  • 允许任一角色访问主页.
  • 允许任一角色访问/ admin页面.但是,除非您具有"admin"角色,否则您将看不到用于管理此页面上的用户和角色的选项卡.
  • 只允许管理员角色访问/ admin页面的子页面,例如/ admin/userview.否则,您将收到"禁止"回复.
  • 请注意,在编辑用户时,由于Flask-Admin,角色的名称会自动填充.
  • 您可以添加和编辑用户和角色.生成的用户将能够登录(除非您设置active = false),如果他们具有"admin"角色,则将能够执行管理.

相关代码位于main.py中,并且明确注释以解释如何使用flask-security复制保护瓶管理面板的过程.

最基本的相关内容如下(第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')
Run Code Online (Sandbox Code Playgroud)

我希望这是有帮助的.