Как защитить панель-колдун-панель с помощью фляжки
Я ищу защищенный веб-API, созданный с помощью Flask, и интегрированный с flask-admin
для обеспечения интерфейса администратора. Я обыскал и обнаружил, что флажок-admin имеет панель администратора в /admin
, и по умолчанию у кого-то есть доступ к ней. Он не предоставляет никакой системы аутентификации и полностью открыт (без какой-либо безопасности), поскольку они не предполагают, что будет использоваться для обеспечения безопасности. Этот API должен использоваться в производстве, поэтому у нас не может быть открытого маршрута /admin
для всех, кто попадает в URL-адрес. Необходима правильная проверка подлинности.
В views.py
я не могу просто поместить маршрут /admin
и обеспечить аутентификацию через декоратор, так как это будет переписывать существующий маршрут, уже созданный с помощью flask-admin
, чтобы вызвать ошибку.
Дальнейшие исследования показывают, что существует два модуля flask-admin
и flask-security
. Я знаю, что flask-admin
имеет метод is_accessible
для его защиты, но он не обеспечивает много функциональности, предоставляемой flask-security
.
Я не нашел там никакого метода для защиты конечной точки /admin
плюс все остальные конечные точки, начинающиеся с /admin
, например /admin/<something>
.
Я смотрю конкретно, чтобы выполнить эту задачу с помощью флеш-безопасности. Если это невозможно, предложите альтернативы.
PS: Я знаю, что я могу заблокировать ngnix
сам, но это будет последний вариант. Если бы я мог иметь систему аутентификации через flask-security
, это было бы хорошо.
Ответы
Ответ 1
Вы должны проверить проект Flask-Security-Admin, я думаю, что он довольно четко описывает то, что вы ищете.
Взято непосредственно из ссылки выше:
- При первом посещении домашней страницы приложения вам будет предложено войти в систему, благодаря Flask-Security.
- Если вы входите в систему с именем пользователя [email protected] и password = password, у вас будет роль "конечный пользователь".
- Если вы входите в систему с именем пользователя [email protected] и password = password, у вас будет роль "admin" .
- Доступ к главной странице разрешен либо для доступа к главной странице.
- Любая роль разрешена для доступа к странице /admin. Однако, если у вас нет роли "admin" , вы не увидите вкладки для администрирования пользователей и ролей на этой странице.
- Только роль администратора разрешена для доступа к подстраницам страницы /admin, например/admin/userview. В противном случае вы получите "запрещенный" ответ.
- Обратите внимание, что при редактировании пользователя имена ролей автоматически заполняются благодаря Flask-Admin.
- Вы можете добавлять и редактировать пользователей и роли. Результирующие пользователи смогут войти (если вы не установите active = false), и, если они имеют роль "admin" , смогут выполнять администрирование.
Соответствующий код находится в main.py и четко прокомментирован, чтобы объяснить, как реплицировать процесс защиты панели flask-admin, используя флай-безопасность.
Самой основной, важной частью для вас является следующая строка (строка 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')
Я надеюсь, что это будет полезно.
Ответ 2
Так как это первый результат для поиска google-поиска с защитой от флеш-безопасности, и пока нет готового решения, я думаю, что могу внести свой вклад.
В проекте flask-admin был запрошен аналогичный вопрос Список проблем, и приведен простой пример использования флай-логина и mogodb здесь.
Я сделал пример, используя SQLAchemy для базы данных sqlite и флеш-безопасности. См. Приложение с образцовой колбой ниже:
#!/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='[email protected]', 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)
Обратитесь к документам с флагом, чтобы узнать как настроить страницу входа в систему.
Надеюсь, что это поможет.
Ответ 3
Здесь содержится информация о безопасности в документации Flask-Admin: http://flask-admin.readthedocs.io/en/latest/introduction/#authorization-permissions
Ответ 4
Я использую ответ @RamiMac для всех под-представлений, но для индекса один (по умолчанию /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()
В моем проекте это происходит сразу после всего моего кода Flask-Admin
, который сам находится в своем собственном запуске script, custom_flaskadmin.py
.