mirror of
https://github.com/matrix-org/matrix-spec
synced 2025-12-20 16:38:37 +01:00
Clarify the differences between the two authentication APIs (#2159)
Some checks failed
Spec / 🔎 Validate OpenAPI specifications (push) Has been cancelled
Spec / 🔎 Check Event schema examples (push) Has been cancelled
Spec / 🔎 Check OpenAPI definitions examples (push) Has been cancelled
Spec / 🔎 Check JSON Schemas inline examples (push) Has been cancelled
Spec / ⚙️ Calculate baseURL for later jobs (push) Has been cancelled
Spec / 📢 Run towncrier for changelog (push) Has been cancelled
Spell Check / Spell Check with Typos (push) Has been cancelled
Spec / 🐍 Build OpenAPI definitions (push) Has been cancelled
Spec / 📖 Build the spec (push) Has been cancelled
Spec / 🔎 Validate generated HTML (push) Has been cancelled
Spec / 📖 Build the historical backup spec (push) Has been cancelled
Some checks failed
Spec / 🔎 Validate OpenAPI specifications (push) Has been cancelled
Spec / 🔎 Check Event schema examples (push) Has been cancelled
Spec / 🔎 Check OpenAPI definitions examples (push) Has been cancelled
Spec / 🔎 Check JSON Schemas inline examples (push) Has been cancelled
Spec / ⚙️ Calculate baseURL for later jobs (push) Has been cancelled
Spec / 📢 Run towncrier for changelog (push) Has been cancelled
Spell Check / Spell Check with Typos (push) Has been cancelled
Spec / 🐍 Build OpenAPI definitions (push) Has been cancelled
Spec / 📖 Build the spec (push) Has been cancelled
Spec / 🔎 Validate generated HTML (push) Has been cancelled
Spec / 📖 Build the historical backup spec (push) Has been cancelled
I tried to summarize MSC3861, and add sections to be able to find quickly how to do something with either API. Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
This commit is contained in:
parent
ccd9e50eb1
commit
b278a4e0ec
1
changelogs/client_server/newsfragments/2159.feature
Normal file
1
changelogs/client_server/newsfragments/2159.feature
Normal file
|
|
@ -0,0 +1 @@
|
|||
Add the OAuth 2.0 based authentication API, as per [MSC3861](https://github.com/matrix-org/matrix-spec-proposals/pull/3861) and its sub-proposals.
|
||||
|
|
@ -292,9 +292,8 @@ and the two requests would be considered distinct because the two are
|
|||
considered separate endpoints. Similarly, if a client logs out and back in
|
||||
between two requests using the same transaction ID, the requests are distinct
|
||||
because the act of logging in and out creates a new device (unless an existing
|
||||
`device_id` is passed to [`POST
|
||||
/_matrix/client/v3/login`](#post_matrixclientv3login)). On the other hand, if a
|
||||
client re-uses a transaction ID for the same endpoint after
|
||||
`device_id` is given during the [login](#login) process). On the other hand, if
|
||||
a client re-uses a transaction ID for the same endpoint after
|
||||
[refreshing](#refreshing-access-tokens) an access token, it will be assumed to
|
||||
be a duplicate request and ignored. See also
|
||||
[Relationship between access tokens and devices](#relationship-between-access-tokens-and-devices).
|
||||
|
|
@ -436,6 +435,8 @@ endpoints it supports.
|
|||
|
||||
## Client Authentication
|
||||
|
||||
{{% changed-in v="1.15" %}} OAuth 2.0 API added to the specification.
|
||||
|
||||
Most API endpoints require the user to identify themselves by presenting
|
||||
previously obtained credentials in the form of an access token.
|
||||
An access token is typically obtained via the [Login](#login) or
|
||||
|
|
@ -449,6 +450,60 @@ free to choose an appropriate format. Server implementors may like to
|
|||
investigate [macaroons](http://research.google.com/pubs/pub41892.html).
|
||||
{{% /boxes/note %}}
|
||||
|
||||
Since Matrix 1.15, the Client-Server specification supports two authentication
|
||||
APIs:
|
||||
|
||||
* The [legacy API](#legacy-api)
|
||||
* The [OAuth 2.0 API](#oauth-20-api)
|
||||
|
||||
The legacy API has existed since the first version of the Matrix specification,
|
||||
while the OAuth 2.0 API has been introduced to rely on a industry standard and
|
||||
its experience rather than implementing a custom protocol that might not follow
|
||||
the best practices.
|
||||
|
||||
A homeserver may support one of those two APIs, or both. The two APIs are
|
||||
mutually incompatible, which means that after logging in, clients MUST only use
|
||||
the API that was used to obtain their current access token.
|
||||
|
||||
{{% boxes/note %}}
|
||||
Currently the OAuth 2.0 API doesn't cover all the use cases of the legacy API,
|
||||
such as automated applications that cannot use a web browser, or
|
||||
user management by [application services](application-service-api/#server-admin-style-permissions).
|
||||
{{% /boxes/note %}}
|
||||
|
||||
### Authentication API discovery
|
||||
|
||||
To discover if a homeserver supports the legacy API, the [`GET /login`](#get_matrixclientv3login)
|
||||
endpoint can be used.
|
||||
|
||||
To discover if a homeserver supports the OAuth 2.0 API, the
|
||||
[`GET /auth_metadata`](#get_matrixclientv1auth_metadata) endpoint can be used.
|
||||
|
||||
In both cases, the server SHOULD respond with 404 and an `M_UNRECOGNIZED` error
|
||||
code if the corresponding API is not supported.
|
||||
|
||||
### Account registration
|
||||
|
||||
With the legacy API, a client can register a new account with the
|
||||
[`/register`](#post_matrixclientv3register) endpoint.
|
||||
|
||||
With the OAuth 2.0 API, a client can't register a new account directly. The end
|
||||
user must do that directly in the homeserver's web UI. However, the client can
|
||||
signal to the homeserver that the user wishes to create a new account with the
|
||||
[`prompt=create`](#user-registration) parameter during authorization.
|
||||
|
||||
### Login
|
||||
|
||||
With the legacy API, a client can obtain an access token by using one of the
|
||||
[login](#legacy-login) methods supported by the homeserver at the [`POST /login`](#post_matrixclientv3login)
|
||||
endpoint. To invalidate the access token the client must call the [`/logout`](#post_matrixclientv3logout)
|
||||
endpoint.
|
||||
|
||||
With the OAuth 2.0 API, a client can obtain an access token by using one of the
|
||||
[grant types](#grant-types) supported by the homeserver and authorizing the
|
||||
proper [scope](#scope), as demonstrated in the [login flow](#login-flow). To
|
||||
invalidate the access token the client must use [token revocation](#token-revocation).
|
||||
|
||||
### Using access tokens
|
||||
|
||||
Access tokens may be provided via a request header, using the Authentication
|
||||
|
|
@ -494,12 +549,14 @@ used to generate a new access token and refresh token, the new access
|
|||
and refresh tokens are now bound to the device associated with the
|
||||
initial refresh token.
|
||||
|
||||
By default, the [Login](#login) and [Registration](#account-registration)
|
||||
processes auto-generate a new `device_id`. A client is also free to
|
||||
generate its own `device_id` or, provided the user remains the same,
|
||||
reuse a device: in either case the client should pass the `device_id` in
|
||||
the request body. If the client sets the `device_id`, the server will
|
||||
invalidate any access and refresh tokens previously assigned to that device.
|
||||
During login or registration, the generated access token should be associated
|
||||
with a `device_id`. The legacy [Login](#legacy-login) and [Registration](#legacy-account-registration)
|
||||
processes auto-generate a new `device_id`, but a client is also free to provide
|
||||
its own `device_id`. With the OAuth 2.0 API, the `device_id` is always provided
|
||||
by the client. The client can generate a new `device_id` or, provided the user
|
||||
remains the same, reuse an existing device. If the client sets the `device_id`,
|
||||
the server will invalidate any access and refresh tokens previously assigned to
|
||||
that device.
|
||||
|
||||
### Refreshing access tokens
|
||||
|
||||
|
|
@ -508,14 +565,13 @@ invalidate any access and refresh tokens previously assigned to that device.
|
|||
Access tokens can expire after a certain amount of time. Any HTTP calls that
|
||||
use an expired access token will return with an error code `M_UNKNOWN_TOKEN`,
|
||||
preferably with `soft_logout: true`. When a client receives this error and it
|
||||
has a refresh token, it should attempt to refresh the access token by calling
|
||||
[`/refresh`](#post_matrixclientv3refresh). Clients can also refresh their
|
||||
access token at any time, even if it has not yet expired. If the token refresh
|
||||
succeeds, the client should use the new token for future requests, and can
|
||||
re-try previously-failed requests with the new token. When an access token is
|
||||
refreshed, a new refresh token may be returned; if a new refresh token is
|
||||
given, the old refresh token will be invalidated, and the new refresh token
|
||||
should be used when the access token needs to be refreshed.
|
||||
has a refresh token, it should attempt to refresh the access token. Clients can
|
||||
also refresh their access token at any time, even if it has not yet expired. If
|
||||
the token refresh succeeds, the client should use the new token for future
|
||||
requests, and can re-try previously-failed requests with the new token. When an
|
||||
access token is refreshed, a new refresh token may be returned; if a new refresh
|
||||
token is given, the old refresh token will be invalidated, and the new refresh
|
||||
token should be used when the access token needs to be refreshed.
|
||||
|
||||
The old refresh token remains valid until the new access token or refresh token
|
||||
is used, at which point the old refresh token is revoked. This ensures that if
|
||||
|
|
@ -528,6 +584,7 @@ and attempt to obtain a new access token by re-logging in. If the error
|
|||
response does not include a `soft_logout: true` property, the client should
|
||||
consider the user as being logged out.
|
||||
|
||||
With the legacy API, refreshing access tokens is done by calling [`/refresh`](#post_matrixclientv3refresh).
|
||||
Handling of clients that do not support refresh tokens is up to the homeserver;
|
||||
clients indicate their support for refresh tokens by including a
|
||||
`refresh_token: true` property in the request body of the
|
||||
|
|
@ -537,6 +594,11 @@ may allow the use of non-expiring access tokens, or may expire access tokens
|
|||
anyways and rely on soft logout behaviour on clients that don't support
|
||||
refreshing.
|
||||
|
||||
With the OAuth 2.0 API, refreshing access tokens is done with the [refresh token
|
||||
grant type](#refresh-token-grant), as demonstrated in the [token refresh
|
||||
flow](#token-refresh-flow). Support for refreshing access tokens is mandatory
|
||||
with this API.
|
||||
|
||||
### Soft logout
|
||||
|
||||
A client can be in a "soft logout" state if the server requires
|
||||
|
|
@ -560,8 +622,24 @@ specifying the device ID it is already using to the login API.
|
|||
with an `M_USER_LOCKED` error code, cannot obtain a new access token until
|
||||
the account has been [unlocked](#account-locking).
|
||||
|
||||
### Account management
|
||||
|
||||
With the legacy API, a client can use several endpoints to allow the user to
|
||||
manage their account like [changing their password](#password-management),
|
||||
[managing their devices](#device-management) or
|
||||
[deactivating their account](#account-deactivation).
|
||||
|
||||
With the OAuth 2.0 API, all account management is done via the homeserver's web
|
||||
UI.
|
||||
|
||||
### Legacy API
|
||||
|
||||
This is the original authentication API that was introduced in the first version
|
||||
of the Client-Server specification and uses custom APIs. Contrary to the OAuth
|
||||
2.0 API, account management is primarily done in the client's interface and as
|
||||
such it does not usually require the end user to be redirected to a web UI in
|
||||
their browser.
|
||||
|
||||
#### User-Interactive Authentication API
|
||||
|
||||
##### Overview
|
||||
|
|
@ -1329,7 +1407,7 @@ The `country` is the two-letter uppercase ISO-3166-1 alpha-2 country
|
|||
code that the number in `phone` should be parsed as if it were dialled
|
||||
from.
|
||||
|
||||
#### Login
|
||||
#### Login {id="legacy-login"}
|
||||
|
||||
A client can obtain access tokens using the [`/login`](#post_matrixclientv3login) API.
|
||||
|
||||
|
|
@ -1458,11 +1536,11 @@ forwarded to the login endpoint during the login process. For example:
|
|||
|
||||
GET /_matrix/static/client/login/?device_id=GHTYAJCE
|
||||
|
||||
#### Account registration
|
||||
#### Account registration {id="legacy-account-registration"}
|
||||
|
||||
{{% http-api spec="client-server" api="registration" %}}
|
||||
|
||||
#### Account management
|
||||
#### Account management {id="legacy-account-management"}
|
||||
|
||||
##### Password management
|
||||
|
||||
|
|
@ -1481,6 +1559,37 @@ MAY reject weak passwords with an error code `M_WEAK_PASSWORD`.
|
|||
|
||||
### OAuth 2.0 API
|
||||
|
||||
{{% added-in v="1.15" %}}
|
||||
|
||||
Contrary to the legacy API that uses custom endpoints and UIA, this
|
||||
authentication API is based on the [OAuth 2.0](https://oauth.net/2/) industry
|
||||
standard introduced in [RFC 6749](https://datatracker.ietf.org/doc/html/rfc6749)
|
||||
and extended by other RFCs, with a few features from [OpenID Connect](https://openid.net/connect/).
|
||||
This allows us to benefit from its experience and from any further enhancements
|
||||
or best practice recommendations.
|
||||
|
||||
The main change for end users with this API is that all the account management
|
||||
occurs in their browser on the homeserver's web UI. This is where they will
|
||||
register a new account or log into an existing account and authorize a client to
|
||||
access their Matrix account. This means that the homeserver has complete control
|
||||
over the requirements to create a new account and is not limited by the steps
|
||||
defined in this specification. It also means that less trust is given to clients
|
||||
because they don't have access to the user's credentials anymore.
|
||||
|
||||
{{% boxes/warning %}}
|
||||
The [User-Interactive Authentication API](#user-interactive-authentication-api)
|
||||
is not compatible with the OAuth 2.0 API, so the endpoints that depend on it for
|
||||
authentication can't be used when an access token is obtained with this API.
|
||||
{{% /boxes/warning %}}
|
||||
|
||||
**Sample flow**
|
||||
|
||||
1. [Discover the OAuth 2.0 server metadata](#server-metadata-discovery).
|
||||
2. [Register the client with the homeserver](#client-registration).
|
||||
3. [Obtain an access token](#login-flow) by authorizing a [scope](#scope) for the client with the [authorization code grant](#authorization-code-grant).
|
||||
4. [Refresh the access token](#token-refresh-flow) with the [refresh token grant](#refresh-token-grant) when it expires.
|
||||
5. [Revoke the tokens](#token-revocation) when the users wants to log out of the client.
|
||||
|
||||
#### Login flow
|
||||
|
||||
Logging in with the OAuth 2.0 API should be done with the [authorization code
|
||||
|
|
|
|||
Loading…
Reference in a new issue