认证与权限

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-tableexecute-sql

资源是参与者希望与之交互的项目——例如特定的数据库或表。某些操作(例如 permissions-debug)不与特定资源相关联。

Datasette 的内置视图权限(view-databaseview-table 等)默认设置为允许——除非您配置额外的权限规则,否则未认证的用户将被允许访问内容。

具有潜在有害影响的权限应默认设置为拒绝。插件作者在设计新插件时应考虑到这一点——例如,datasette-upload-csvs 插件默认设置为拒绝,以防止安装意外地允许未认证的用户通过上传 CSV 文件创建新表。

使用“allow”块定义权限

在 Datasette 中定义权限的标准方法是使用一个 "allow" 块。这是一个描述哪些参与者允许执行某项权限的 JSON 文档。

最基本的 allow 块形式是这样(允许示例拒绝示例

{
    "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"
    }
}

cleopaws 示例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 调试页面。

默认:拒绝

debug-menu

控制是否在导航菜单中显示各种调试页面。

默认:拒绝