认证与权限¶
Datasette 默认不要求认证。Datasette 实例的任何访问者都可以浏览完整数据并执行只读 SQL 查询。
Datasette 的插件系统可用于添加多种不同风格的认证方式,例如用户账户、单点登录或 API 密钥。
参与者¶
通过插件,Datasette 可以支持认证用户(通过 cookies)和认证 API 代理(通过认证令牌)。“actor”一词用于涵盖这两种情况。
对 Datasette 的每个请求都有一个相关的参与者值,在代码中可通过 request.actor
获取。对于未认证的请求,其值为 None
;对于认证用户或 API 代理,则为一个兼容 JSON 的 Python 字典。
参与者字典可以是任意结构——该数据结构的设计取决于插件。一个有用的约定是包含一个 "id"
字符串,如下面的“root”参与者所示。
插件可以使用插件钩子 actor_from_request(datasette, request) 实现自定义逻辑,以便根据传入的 HTTP 请求对参与者进行认证。
使用“root”参与者¶
Datasette 目前几乎将所有形式的认证都留给插件实现——例如 datasette-auth-github。
唯一的例外是“root”账户,您可以在本地计算机上使用 Datasette 时登录该账户。这提供了对少量调试功能的访问权限。
要以 root 身份登录,请使用 --root
命令行选项启动 Datasette,如下所示
$ datasette --root
http://127.0.0.1:8001/-/auth-token?token=786fc524e0199d70dc9a581d851f466244e114ca92f33aa3b42a139e9388daa7
INFO: Started server process [25801]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://127.0.0.1:8001 (Press CTRL+C to quit)
第一行的 URL 包含一个一次性令牌,可用于在您的浏览器中以“root”参与者身份登录。点击该链接,然后访问 http://127.0.0.1:8001/-/actor
以确认您已认证为一个类似于此的参与者
{
"id": "root"
}
权限¶
Datasette 内置了广泛的权限系统,该系统可通过插件进一步扩展和定制。
权限系统回答的关键问题是:
此参与者是否允许执行此操作,可选地针对此特定资源?
参与者如上所述。
操作是一个字符串,描述参与者希望执行的操作。完整列表如下所示——示例包括 view-table
和 execute-sql
。
资源是参与者希望与之交互的项目——例如特定的数据库或表。某些操作(例如 permissions-debug
)不与特定资源相关联。
Datasette 的内置视图权限(view-database
、view-table
等)默认设置为允许——除非您配置额外的权限规则,否则未认证的用户将被允许访问内容。
具有潜在有害影响的权限应默认设置为拒绝。插件作者在设计新插件时应考虑到这一点——例如,datasette-upload-csvs 插件默认设置为拒绝,以防止安装意外地允许未认证的用户通过上传 CSV 文件创建新表。
使用“allow”块定义权限¶
在 Datasette 中定义权限的标准方法是使用一个 "allow"
块。这是一个描述哪些参与者允许执行某项权限的 JSON 文档。
{
"allow": {
"id": "root"
}
}
这将匹配任何 "id"
属性为 "root"
的参与者——例如,一个看起来像这样的参与者
{
"id": "root",
"name": "Root User"
}
allow 块可以使用 false
指定“拒绝所有”(示例)
{
"allow": false
}
将 "allow"
设置为 true
允许所有访问(示例)
{
"allow": true
}
Allow 键可以提供一个值列表。这将匹配具有这些值中任何一个的参与者(允许示例,拒绝示例)
{
"allow": {
"id": ["simon", "cleopaws"]
}
}
这将匹配任何 "id"
为 "simon"
或 "cleopaws"
的参与者。
参与者可以具有包含值列表的属性。这些属性将与 allow 块中的值列表进行匹配。考虑以下参与者
{
"id": "simon",
"roles": ["staff", "developer"]
}
此 allow 块将向任何将 "developer"
作为其角色之一的参与者提供访问权限(允许示例,拒绝示例)
{
"allow": {
"roles": ["developer"]
}
}
请注意,“roles”并非 Datasette 内置的概念——它是一个插件可以选择实现和使用的约定。
如果您想为特定键具有值的任何参与者提供访问权限,请使用 "*"
。例如,要匹配任何已登录用户,请指定以下内容(允许示例,拒绝示例)
{
"allow": {
"id": "*"
}
}
您可以使用 allow 块中的特殊键 "unauthenticated": true
指定只允许未认证的参与者(来自匿名 HTTP 请求)访问(允许示例,拒绝示例)
{
"allow": {
"unauthenticated": true
}
}
Allow 键起到“或”机制的作用。如果参与者的任何 JSON 属性与 allow
块中对应列表中的任何值匹配,则该参与者将能够执行查询。以下块将允许 role
为 "ops"
的用户或 id
为 "simon"
或 "cleopaws"
的用户访问
{
"allow": {
"id": ["simon", "cleopaws"],
"role": "ops"
}
}
/-/allow-debug 工具¶
/-/allow-debug
工具允许您针对不同的 "actor"
JSON 对象尝试不同的 "action"
块。您可以在这里尝试:https://latest.datasette.io/-/allow-debug
在 metadata.json 中配置权限¶
您可以使用元数据配置中的 "allow"
键限制允许谁查看 Datasette 实例的不同部分。
您可以控制以下内容:
对整个 Datasette 实例的访问
对特定数据库的访问
对特定表和视图的访问
对特定预设查询的访问
如果用户无法访问特定数据库,他们将无法访问该数据库中的表、视图或查询。如果用户无法访问实例,他们将无法访问任何数据库、表、视图或查询。
控制对实例的访问¶
以下是如何将对整个 Datasette 实例的访问限制为仅 "id": "root"
用户
{
"title": "My private Datasette instance",
"allow": {
"id": "root"
}
}
要拒绝所有用户访问,可以使用 "allow": false
{
"title": "My entirely inaccessible instance",
"allow": false
}
这样做的原因之一是您正在使用 Datasette 插件(例如 datasette-permissions-sql)来代替控制权限。
控制对特定数据库的访问¶
要将对特定 private.db
数据库的访问限制为仅认证用户,请按如下方式使用 "allow"
块
{
"databases": {
"private": {
"allow": {
"id": "*"
}
}
}
}
控制对特定表和视图的访问¶
要限制对 bakery.db
数据库中 users
表的访问
{
"databases": {
"bakery": {
"tables": {
"users": {
"allow": {
"id": "*"
}
}
}
}
}
}
这同样适用于 SQL 视图——您可以将它们的名称列在上面的 "tables"
块中,就像列出普通表一样。
警告
以这种方式限制对表和视图的访问,并不能阻止用户使用任意 SQL 查询它们,例如这样。
如果您限制对特定表的访问,您还应该使用 "allow_sql"
块来防止用户通过自己的 SQL 查询绕过限制——请参阅控制执行任意 SQL 的能力。
控制对特定预设查询的访问¶
预设查询允许您在 metadata.json
中配置用户可以执行的命名 SQL 查询。这些查询可以设置为既可以读取数据库,也可以写入数据库,因此控制谁可以执行它们可能很重要。
要将对 dogs.db
数据库中 add_name
预设查询的访问限制为仅root 用户
{
"databases": {
"dogs": {
"queries": {
"add_name": {
"sql": "INSERT INTO names (name) VALUES (:name)",
"write": true,
"allow": {
"id": ["root"]
}
}
}
}
}
}
控制执行任意 SQL 的能力¶
Datasette 默认允许任何网站访问者执行自己的自定义 SQL 查询,例如使用数据库页面上的表单或通过向表页面追加 ?_where=
参数,例如这样。
对此能力的访问由execute-sql权限控制。
禁用任意 SQL 查询的最简单方法是在首次启动 Datasette 时使用default_allow_sql 设置。
您也可以使用一个 "allow_sql"
块来控制谁被允许执行任意 SQL 查询。
要阻止任何用户执行任意 SQL 查询,请使用此配置
{
"allow_sql": false
}
要仅允许root 用户对实例中的所有数据库执行 SQL,请使用以下配置
{
"allow_sql": {
"id": "root"
}
}
要仅限制此能力对一个特定数据库生效,请使用此配置
{
"databases": {
"mydatabase": {
"allow_sql": {
"id": "root"
}
}
}
}
在插件中检查权限¶
Datasette 插件可以使用datasette.permission_allowed(...) 方法检查参与者是否具有执行某项操作的权限。
Datasette 核心执行多项权限检查,详见下文。插件可以实现permission_allowed(datasette, actor, action, resource) 插件钩子,参与关于参与者是否应能执行指定操作的决策。
actor_matches_allow()¶
希望实现相同 "allow"
块权限方案的插件可以利用 datasette.utils.actor_matches_allow(actor, allow)
函数
from datasette.utils import actor_matches_allow
actor_matches_allow({"id": "root"}, {"id": "*"})
# returns True
当前认证的参与者可通过 request.actor
供插件使用。
权限调试工具¶
位于 /-/permissions
的调试工具仅对认证的 root 用户(或根据插件被授予 permissions-debug
操作的任何参与者)可用。
它显示 Datasette 实例执行的最近三十次权限检查。
这旨在帮助管理员和插件作者准确理解权限检查是如何执行的,以便有效地配置 Datasette 的权限系统。
内置权限¶
本节列出了 Datasette 核心执行的所有权限检查,以及传递的 resource
(如果存在)。
view-instance¶
顶级权限 - 参与者被允许查看此实例内的任何页面,从 https://latest.datasette.io/ 开始
默认:允许。
view-database¶
参与者被允许查看数据库页面,例如 https://latest.datasette.io/fixtures
resource
- 字符串数据库的名称
默认:允许。
view-database-download¶
参与者被允许下载数据库,例如 https://latest.datasette.io/fixtures.db
resource
- 字符串数据库的名称
默认:允许。
view-table¶
参与者被允许查看表(或视图)页面,例如 https://latest.datasette.io/fixtures/complex_foreign_keys
resource
- 元组:(字符串, 字符串)数据库的名称,然后是表的名称
默认:允许。
view-query¶
参与者被允许查看(和执行)预设查询页面,例如 https://latest.datasette.io/fixtures/pragma_cache_size - 这包括执行可写预设查询。
resource
- 元组:(字符串, 字符串)数据库的名称,然后是预设查询的名称
默认:允许。
execute-sql¶
参与者被允许对特定数据库运行任意 SQL 查询,例如 https://latest.datasette.io/fixtures?sql=select+100
resource
- 字符串数据库的名称
默认:允许。另请参阅default_allow_sql 设置。
permissions-debug¶
参与者被允许查看 /-/permissions
调试页面。
默认:拒绝。