mirror of
https://github.com/simonw/datasette.git
synced 2026-07-16 20:44:35 +02:00
Return 401 for invalid or expired bearer tokens
Invalid dstok_ tokens - bad signature, malformed payload, expired, or presented while allow_signed_tokens is off - previously degraded the request to anonymous, so clients saw a 403 permission error or worse, a 200 with anonymous-visible data. Token handlers can now raise TokenInvalid for tokens they recognize but reject; Datasette responds with 401, the canonical JSON error body and a WWW-Authenticate: Bearer error="invalid_token" header, even when a valid cookie is also present. Bearer tokens no registered handler recognizes are still ignored, so authentication plugins with their own token formats keep working. TokenInvalid is exported from the datasette package for use by plugin token handlers. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GrHZSypDfMnym1tM5XJAFZ
This commit is contained in:
parent
b2cdc81d34
commit
aaaffe45b8
11 changed files with 214 additions and 45 deletions
|
|
@ -1156,14 +1156,17 @@ registered via `register_token_handler`; the default is
|
|||
- **Format:** `dstok_` + itsdangerous-signed payload (namespace `token`)
|
||||
containing `a` (actor id), `t` (creation Unix time), optional `d`
|
||||
(duration seconds), optional `_r` (restrictions).
|
||||
- **Verification** returns no actor when: `allow_signed_tokens` is off, the
|
||||
signature is invalid, `t` is missing/non-integer, or the token is expired.
|
||||
The effective duration is `d` capped by `max_signed_tokens_ttl` (default 0
|
||||
= no cap; a non-zero setting also imposes a TTL on tokens without `d`).
|
||||
- **Verification:** a `dstok_`-prefixed token that fails verification —
|
||||
`allow_signed_tokens` off, invalid signature, missing/non-integer `t`,
|
||||
malformed `d`, or expired — raises `TokenInvalid`, and the request fails
|
||||
with **401**, the canonical error body and a
|
||||
`WWW-Authenticate: Bearer error="invalid_token"` header (even if a valid
|
||||
`ds_actor` cookie is also present). Tokens with prefixes no registered
|
||||
handler recognizes are ignored (they may belong to an auth plugin). The
|
||||
effective duration is `d` capped by `max_signed_tokens_ttl` (default 0 =
|
||||
no cap; a non-zero setting also imposes a TTL on tokens without `d`).
|
||||
- **Resulting actor:** `{"id": <a>, "token": "dstok"}` plus `"_r"` and
|
||||
`"token_expires"` when applicable. Invalid/expired tokens silently produce
|
||||
an anonymous request (no 401) — the failure then surfaces as a 403 from
|
||||
whatever permission check the request hits.
|
||||
`"token_expires"` when applicable.
|
||||
|
||||
**Restrictions (`_r`)** (default_permissions/restrictions.py):
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue