公司动态
Invenio RBAC 访问控制完整指南:用权限工厂与搜索过滤器保护 REST API 的实战教程
Invenio RBAC 访问控制完整指南用权限工厂与搜索过滤器保护 REST API 的实战教程【免费下载链接】invenioInvenio digital library framework项目地址: https://gitcode.com/gh_mirrors/in/invenio如果你正在用Invenio 数字图书馆框架搭建自己的知识库或数字仓库那么RBAC 访问控制一定是绕不开的一环。Invenio 自带的访问控制系统可以精细到某条记录只有它的主人能看。这篇文章将通过一个完整实战教你用**权限工厂permission factory保护详情接口、用搜索过滤器search filter**保护检索接口让你的 REST API 既开放又安全新手也能照着做。为什么数字图书馆必须做好 REST API 权限控制Invenio 是欧洲核子研究中心CERN开源的大规模数字仓库框架被 CERN Document Server、INSPIRE 等众多知名系统采用。它的 REST API 天然暴露出两类接口接口类型示例路径保护目标 搜索接口/api/records只返回当前用户有权查看的记录 详情接口/api/records/id只有记录的主人才能取回该记录假设你上传了一篇我的秘密论文默认情况下任何人都能通过这两个接口拿到它。我们要做的就是让系统自动判断这个人能不能看这条记录。Invenio 的 Auth 模块族docs/documentation/bundles/auth.rst为此提供了一整套组件invenio-access核心 RBAC 引擎支持对象级权限invenio-accounts用户/角色管理、注册、密码恢复、会话保护invenio-oauth2server基于 OAuth 2.0 访问令牌认证 REST APIinvenio-oauthclient支持 ORCID、GitHub 等第三方登录先搞懂三个概念Need、Permission 与 RoleInvenio 的权限体系建立在最小访问单元之上理解这三个词后面全部水到渠成Need需求项最小粒度的访问声明。UserNeed(1)表示是 1 号用户RoleNeed(admin)表示拥有管理员角色Permission权限一组 Need 的集合。Permission(UserNeed(1), RoleNeed(admin))表示是 1 号用户或管理员即可通过Role角色把多个用户组织起来方便批量授权 一句话记忆Need 是原子Permission 是分子RBAC 就是用它们拼出任意复杂的访问规则。实战第一步把权限存进记录里保护数据的前提是数据里得有权限信息。最简单的做法是给记录加一个owner字段{ title: My secret publication, owner: 1 }但要让 Invenio 真正认识这个字段需要同时补全数据模型的三件套详见 docs/documentation/main-concepts/managing-access.rst文件作用类比JSONSchema定义字段结构数据库表结构新增一列Elasticsearch mapping定义索引方式描述数据如何被检索Marshmallow schema定义输出渲染描述如何把一行数据展示给用户三处都加上owner: { type: integer }后权限数据就随记录一起流转了。实战第二步权限工厂守护详情接口详情接口一次只处理一条记录正好适合拿记录反推权限。这就是权限工厂的职责输入一条记录输出一个 Permission 对象。from invenio_access import Permission from flask_principal import UserNeed def my_permission_factory(recordNone): return Permission(UserNeed(record[owner]))逻辑非常直观当前登录用户current_user的 ID 必须等于记录里的owner否则接口返回 403。由于 Permission 可以组合任意多个 Need你甚至能在这里写出主人或编辑部管理员或社区成员这类复杂规则。实战第三步搜索过滤器守护检索接口搜索接口面对的可能是上百万条记录逐条调权限工厂显然不现实。这时需要搜索过滤器它在查询执行时直接注入一条 Elasticsearch 过滤条件从源头把没权限的记录排除掉。from elasticsearch_dsl import Q from flask_security import current_user from invenio_search.api import DefaultFilter, RecordsSearch def permission_filter(): return [Q(match, ownercurrent_user.get_id())] class MyRecordSearch(RecordsSearch): class Meta: index records default_filter DefaultFilter(permission_filter)⚠️一个重要细节权限工厂是记录 → 权限 → 校验用户搜索过滤器是用户 → 条件 → 过滤记录两者从相反的方向做同一件事。因此你必须保证两者产生完全一致的结果否则会出现搜得到却打不开或搜不到却打得开的诡异现象。最后一步给 REST API 端点挂上保护把上面两个组件配置到端点上即可生效RECORDS_REST_ENDPOINTS { recid: dict( # ... search_classMyRecordSearch, read_permission_factory_impmy_permission_factory, # ... ), }这里只保护了读操作。别忘了REST API 还支持增删改可参考 docs/getting-started/quickstart/crud-operations.rst 了解基本用法创建、更新、删除操作应分别配上自己的权限工厂形成闭环。进阶两种更灵活的权限存储方案玩具示例的owner字段够用吗大多数生产场景会更复杂。官方文档给出了两种进阶思路 计算式权限Computed rights——用记录里已有的属性动态推导权限避免权限与其他字段脱节{ visibility: restricted, owners: [1, 2], communities: [blr] }同一份数据读操作可能对所有人开放看文件要求UserNeed(1)、UserNeed(2)或RoleNeed(blr-curators)编辑则仅限两位主人——不同操作、不同权限全部由权限工厂算出来。 显式权限Explicit rights——把权限直接写进记录即使代码变了也能一眼看出谁有什么权限还能通过记录修订历史做审计{ _access: { read: { systemroles: [campus_user] }, update: { users: [1], roles: [curators] } } }生产环境安全加固清单权限体系之上Invenio 还有一批默认即安全的配套设置docs/documentation/main-concepts/securing-your-instance.rst上线前请逐项核对✅强随机 SECRET_KEY用于签名会话切勿提交到代码库不同环境用不同密钥✅APP_ALLOWED_HOSTS白名单限制可服务的域名防 Host 头攻击✅WSGI_PROXIES如实声明前置代理数量防止 IP 伪造✅REST_CSRF_ENABLED开启 REST 接口的 CSRF 校验Bearer Token 请求自动跳过总结 本文的完整路径可以浓缩为一张图存权限JSONSchema ES mapping Marshmallow→权限工厂守详情搜索过滤器守检索→端点配置挂到RECORDS_REST_ENDPOINTS四步走完你的 Invenio REST API 就实现了对象级 RBAC 保护。更深入的 RBAC 用法可以查阅项目文档 docs/documentation/bundles/auth.rst 中列出的 Invenio-Access 模块文档祝你搭建出安全又高效的数字图书馆【免费下载链接】invenioInvenio digital library framework项目地址: https://gitcode.com/gh_mirrors/in/invenio创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考