基于Flask-User构建的KegElements的三层权限模型
项目描述
一个关于Keg应用中认证和授权相关事宜的一站式商店。
简介
基于Keg和KegElements构建的啤酒弹跳器提供了一系列管理授权和认证的功能。啤酒弹跳器允许您选择在您的应用程序中处理哪些功能。它通过提供每个功能的Mixin类来实现,您可以选择性地将这些类混入您的实体(可能是User
实体)。
可用的混入包括
三层权限系统
基于密码的认证和密码历史记录
登录历史记录
有关如何使用这些功能的详细信息,请参阅以下部分。
主键要求
请注意,每个mixin将自动确定您的实体主键。但是,您的实体必须恰好有一个主键,并且必须将其指定为SQLAlchemy声明性类的属性。
权限
为了使用KegBouncer的授权功能来保护Keg视图,您还需要Flask-Login。然而,KegBouncer的模型不需要这个依赖。
keg_bouncer.mixins.PermissionMixin
提供了一种三级权限模型。它管理四种类型的实体
用户
权限(用于描述系统内可以受保护的行动)
用户组(按最能满足业务需求的方式分组用户)
权限包(按最能满足系统的方式分组权限)
我们称之为“三级”权限模型,因为用户可以通过三种方式获得权限
直接
通过权限包
通过用户组
这个术语是为了将此权限模型与其他模型区分开来,如允许任何深度的层次结构的RBAC。技术上,这个三级模型是RBAC的特殊情况。
关于术语“角色”的说明:虽然这个模型在技术上是一种广泛使用的基于角色的访问控制(RBAC)的特殊情况,但我们尽量避免使用高度模糊的术语“角色”。
用法
要将权限功能添加到您的用户实体中,像这样继承PermissionMixin
import flask_login # Only necessary if using KegBouncer to protect you views.
from sqlalchemy import import Column, Integer, String
Base = sqlalchemy.ext.declarative.declarative_base()
class User(Base, flask_login.UserMixin, keg_bouncer.model.mixins.PermissionMixin):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
保护视图和组件
为了保护您应用程序的各个部分,您可以使用keg_bouncer.auth
提供的工具
为了利用这些工具,您的User
实体也需要混入flask_login.UserMixin
。
使用
if
块并检查权限# ... if keg_bouncer.auth.current_user_has_permissions('launch-missiles'): launch_missiles()
装饰一个函数
# ... @keg_bouncer.auth.requires_permissions('launch-missiles') def launch_missiles(target=Enemy()) # ...
从
ProtectedBaseView
继承# ... class LaunchMissilesView(keg_bouncer.auth.ProtectedBaseView): requires_permission = 'launch-missiles'
迁移
KegBouncer使用Alembic来管理迁移,并假定您的应用程序也是如此。
要使用KegBouncer提供的迁移,您需要告诉Alembic在哪里找到修订版。在您的应用程序的alembic.ini
文件中,调整您的version_locations设置以包括KegBouncer的版本文件夹。
[alembic]
version_locations = alembic/versions keg_bouncer:alembic/versions
如果您运行alembic heads,您现在应该看到两个heads,一个用于您的应用程序,一个用于KegBouncer。
$ alembic heads
51ba1b47505e (application) (head)
13d265b97e4d (keg_bouncer) (head)
应用程序有多个heads是完全正常的,但您需要独立升级它们。更好的选择是将两个heads合并为一个。使用alembic merge命令来完成此操作。
$ alembic merge -m "pull KegBouncer into application" 51ba1b 13d265
Generating /path/to/app/alembic/versions/31b094b2844f_pull_keg_bouncer_into_application.py ... done
如果您再次运行alembic heads,您会发现只有一个heads。
$ alembic heads
31b094b2844f (application, keg_bouncer) (head)
此外,在这个合并修订版中,您还需要为您的User
实体(它混入了keg_bouncer.model.mixins.PermissionMixin)创建一些链接表。
基于密码的认证
要将基于密码的认证添加到您的实体中,您需要动态构建一个密码mixin对象并将其混入到您的实体中。
from keg_bouncer.model import mixins
from passlib.context import CryptContext
import sqlalchemy as sa
crypt_context = CryptContext(schemes=['bcrypt'])
# This mixin is optional but allows you to add additional fields to the password history table.
class OptionalAdditionalFields(object):
another_field = sa.Column(sa.Integer)
password_history_mixin = mixins.make_password_mixin(
OptionalAdditionalFields, # [optional] Allows you to add more fields to the password
# history table via a mixin
crypt_context=crypt_context # [optional, but must be provided here or via another means]
# Configures the CryptContext for hashing and verifying
)
class User(password_history_mixin):
default_crypt_context = crypt_context # An alternative way of specifying your CryptContext
# Yet another way to specify your CryptContext
def get_crypt_context(self):
return crypt_context
help(User.set_password) # Adds password to password history
help(User.verify_password) # Verifies a password against most recent password
help(User.is_password_used_previously) # Looks for password in history
help(User.password_history_entity) # SQLAlchemy entity defining password history entries
User.password_history # SQLAlchemy relationship for past passwords;
# sorted in reverse chronological order
注意:如果您使用is_password_used_previously
或类似的概念,您选择的散列算法可以极大地影响性能,因为密码验证是有意设计为缓慢的。例如,使用bcrypt
而不是sha256_crypt
可以使您大约快两倍地验证密码。这在您在旧密码中筛选时会有很大影响。
登录历史记录
要将登录历史记录添加到您的实体中,您需要动态构建一个历史记录mixin对象并将其混入到您的实体中。
from keg_bouncer.model import mixins
import sqlalchemy as sa
# This mixin is optional but allows you to add additional fields to the login history table.
class OptionalAdditionalFields(object):
another_field = sa.Column(sa.Integer)
login_history_mixin = mixins.make_login_history_mixin(
OptionalAdditionalFields, # [optional] Allows you to add more fields to the login history
# table via a mixin
)
class User(login_history_mixin):
pass
help(User.login_history_entity) # SQLAlchemy entity defining login history entries
User.login_history # SQLAlchemy relationship for past logins;
# sorted in reverse chronological order
# Example use:
def register_login(user):
user.login_history.insert(0, user.login_history_entity(is_login_successful=True))
开发
分支和状态
master
:我们的“生产”分支
所有其他分支都是功能分支。
项目需求
查看 requirements
目录中的所需文件和注意事项。
您应该克隆 Keg 和 KegElements,然后执行
pip install -e .
以获取工作副本。由于这些库是新的,它们可能会频繁更改。如果遇到问题,请阅读 requirements 文件中的说明。
有一个名为
build-wheelhouse.py
的脚本,可以在添加了新的需求时运行。它始终重新构建wheel-only.txt
中的库,因此 Git 将始终显示它们已更改。但如果它们实际上没有更改,您应该撤销这些文件,以免将“静态”添加到提交中。
开发环境
为了快速设置开发时的虚拟环境,您可以使用提供的脚本之一。
如果您使用 pyenv
+ virtualenv
,请使用 source scripts/make-env-venv.sh
。
如果您使用 vex
,请使用 source scripts/make-env-vex.sh
。
代码检查
通过安装预提交钩子来防止提交代码检查错误。
ln -s scripts/pre-commit .git/hooks
项目详情
下载文件
下载适用于您平台的文件。如果您不确定选择哪个,请了解有关 安装软件包 的更多信息。
源代码分发
构建分发
KegBouncer-2.2.4.tar.gz 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | d29a95e01fa57d3945a352f0a97957090b0e2f646afcff3a6a1809a9a48e9c1d |
|
MD5 | c02364f9952f7440180e739e0a731c59 |
|
BLAKE2b-256 | f102aa48f7d8ccc70aef049623ed5ccbd9093c94a292f7715de0dcd7ce698be5 |
KegBouncer-2.2.4-py2.py3-none-any.whl 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 2b2611c85f7817094136ac7d6c57cd5cb1cf80366fcd93801618be42392231cc |
|
MD5 | 46de76cb9c7a03c28abffb20dec3d7c1 |
|
BLAKE2b-256 | 3b99e2aca61c530bb946994401fe0dd63ccee7a0dd1e85d57f5ee6075e393e85 |