mirror of
https://github.com/matrix-org/matrix-spec
synced 2026-03-01 17:24:10 +01:00
Merge 4ceec843a9 into be21886a73
This commit is contained in:
commit
45d425a404
1
changelogs/client_server/newsfragments/2320.feature
Normal file
1
changelogs/client_server/newsfragments/2320.feature
Normal file
|
|
@ -0,0 +1 @@
|
|||
Add the OAuth 2.0 Device Authorization Grant (RFC 8628) as a supported grant type, as per [MSC4341](https://github.com/matrix-org/matrix-spec-proposals/pull/4341).
|
||||
|
|
@ -1720,14 +1720,25 @@ authentication type.
|
|||
|
||||
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).
|
||||
3. Obtain an access token by authorizing a [scope](#scope) for the client with
|
||||
one of the supported grant types:
|
||||
- Use the [authorization code grant](#authorization-code-grant) via the
|
||||
[login flow](#login-flow) for clients with access to a web browser.
|
||||
- {{% added-in v="1.18" %}} Use the [device authorization grant](#device-authorization-grant) via the
|
||||
[device authorization flow](#device-authorization-flow) for clients on
|
||||
devices with limited input capabilities (e.g. CLI applications or embedded devices)
|
||||
where the user completes authorization on a separate device.
|
||||
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
|
||||
grant](#authorization-code-grant). In the context of the Matrix specification,
|
||||
grant](#authorization-code-grant) for clients that have access to a web browser.
|
||||
For clients on devices with limited input capabilities, the
|
||||
[device authorization flow](#device-authorization-flow) can be used instead.
|
||||
|
||||
In the context of the Matrix specification,
|
||||
this means requesting a [scope](#scope) including full client-server API
|
||||
read/write access and allocating a device ID.
|
||||
|
||||
|
|
@ -1873,6 +1884,148 @@ Sample response:
|
|||
Finally, the client can call the [`/whoami`](#get_matrixclientv3accountwhoami)
|
||||
endpoint to get the user ID that owns the access token.
|
||||
|
||||
#### Device authorization flow
|
||||
|
||||
{{% added-in v="1.18" %}}
|
||||
|
||||
The device authorization flow allows clients to obtain an access token without
|
||||
needing to directly interact with a web browser. Instead, the user completes
|
||||
authorization on a web browser that can be on a separate device. This is useful
|
||||
for devices with limited input capabilities (such as CLI applications or
|
||||
embedded devices) or where the redirect handling may be unreliable (such as a
|
||||
desktop applications).
|
||||
|
||||
This flow uses the [device authorization grant](#device-authorization-grant).
|
||||
|
||||
In the context of the Matrix specification, this means requesting a
|
||||
[scope](#scope) including full client-server API read/write access and
|
||||
allocating a device ID, as with the [login flow](#login-flow).
|
||||
|
||||
Once the client has retrieved the [server metadata](#server-metadata-discovery),
|
||||
it needs to generate the following value:
|
||||
|
||||
- `device_id`: a unique identifier for this device; see the
|
||||
[`urn:matrix:client:device:<device_id>`](#device-id-allocation) scope token.
|
||||
|
||||
**Device authorization request**
|
||||
|
||||
The client sends a `application/x-www-form-urlencoded` encoded `POST` request to
|
||||
the `device_authorization_endpoint` as defined in
|
||||
[RFC 8628 section 3.1](https://datatracker.ietf.org/doc/html/rfc8628#section-3.1):
|
||||
|
||||
| Parameter | Value |
|
||||
|-------------|----------------------------------------------------------------|
|
||||
| `client_id` | The client ID returned from client registration. |
|
||||
| `scope` | `urn:matrix:client:api:* urn:matrix:client:device:<device_id>` with the `device_id` generated previously. |
|
||||
|
||||
Sample device authorization request:
|
||||
|
||||
```http
|
||||
POST /oauth2/device HTTP/1.1
|
||||
Host: account.example.com
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
|
||||
client_id=s6BhdRkqt3&scope=urn%3Amatrix%3Aclient%3Aapi%3A%2A%20urn%3Amatrix%3Aclient%3Adevice%3AAABBBCCCDDD
|
||||
```
|
||||
|
||||
**Device authorization response**
|
||||
|
||||
The server responds with a JSON object as defined in
|
||||
[RFC 8628 section 3.2](https://datatracker.ietf.org/doc/html/rfc8628#section-3.2),
|
||||
containing:
|
||||
|
||||
| Parameter | |
|
||||
|------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `device_code` | The device verification code. |
|
||||
| `user_code` | An end-user verification code. |
|
||||
| `verification_uri` | The end-user verification URI on the authorization server. |
|
||||
| `verification_uri_complete` | Optionally, the URI which doesn't require the user to manually type the `user_code`, designed for non-textual transmission. |
|
||||
| `expires_in` | The lifetime in seconds of the `device_code` and `user_code`. |
|
||||
| `interval` | The minimum number of seconds the client should wait between polling requests to the token endpoint. If omitted, clients should default to 5. |
|
||||
|
||||
It is RECOMMENDED that the server provides a `verification_uri_complete` such
|
||||
that the user does not need to type in the `user_code`.
|
||||
|
||||
Sample response:
|
||||
|
||||
```json
|
||||
{
|
||||
"device_code": "GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS",
|
||||
"user_code": "WDJB-MJHT",
|
||||
"verification_uri": "https://account.example.com/link",
|
||||
"verification_uri_complete": "https://account.example.com/link?user_code=WDJB-MJHT",
|
||||
"expires_in": 1800,
|
||||
"interval": 5
|
||||
}
|
||||
```
|
||||
|
||||
**User interaction**
|
||||
|
||||
The client conveys the `verification_uri_complete` (and/or `verification_uri`
|
||||
and `user_code`) to the user. How the client does this depends on the
|
||||
specific device characteristics and use case. For example:
|
||||
|
||||
- A CLI application could display the `verification_uri` and `user_code` as text
|
||||
for the user to type into their browser on another device.
|
||||
- An embedded device with a screen could encode the `verification_uri_complete`
|
||||
(with fallback to `verification_uri`) as a QR code for the user to scan with
|
||||
their phone.
|
||||
- A desktop application running on a platform that does not support callbacks
|
||||
could launch the `verification_uri_complete` (with fallback to
|
||||
`verification_uri`) in the system browser.
|
||||
|
||||
The user opens the verification URI in a web browser, which may be on another
|
||||
device, and completes authentication and authorization.
|
||||
|
||||
**Token polling**
|
||||
|
||||
While the user is completing authorization, the client polls the
|
||||
`token_endpoint` for the outcome, at intervals no shorter than the `interval`
|
||||
value from the device authorization response.
|
||||
|
||||
The poll request is a `POST` to the `token_endpoint` with the following
|
||||
parameters, encoded as `application/x-www-form-urlencoded` in the body:
|
||||
|
||||
| Parameter | Value |
|
||||
|---------------|----------------------------------------------------------------|
|
||||
| `grant_type` | `urn:ietf:params:oauth:grant-type:device_code` |
|
||||
| `device_code` | The `device_code` from the device authorization response. |
|
||||
| `client_id` | The client ID returned from client registration. |
|
||||
|
||||
Sample token polling request:
|
||||
|
||||
```http
|
||||
POST /oauth2/token HTTP/1.1
|
||||
Host: account.example.com
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
|
||||
grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code&device_code=GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS&client_id=s6BhdRkqt3
|
||||
```
|
||||
|
||||
The server responds as defined in [RFC 8628 section
|
||||
3.5](https://datatracker.ietf.org/doc/html/rfc8628#section-3.5):
|
||||
|
||||
- While authorization is pending, the server returns an `authorization_pending`
|
||||
error (or `slow_down` if the client is polling too frequently).
|
||||
- If authorization is denied, the server returns an `access_denied` error.
|
||||
- If the device code expires, the server returns an `expired_token` error.
|
||||
- On successful authorization, the server returns a JSON object containing the
|
||||
access token, token type, expiration time, refresh token, and scope:
|
||||
|
||||
```json
|
||||
{
|
||||
"access_token": "2YotnFZFEjr1zCsicMWpAA",
|
||||
"token_type": "Bearer",
|
||||
"expires_in": 299,
|
||||
"refresh_token": "tGz3JOkF0XG5Qx2TlKWIA",
|
||||
"scope": "urn:matrix:client:api:* urn:matrix:client:device:AAABBBCCCDDD"
|
||||
}
|
||||
```
|
||||
|
||||
Finally, the client can call the [`/whoami`](#get_matrixclientv3accountwhoami)
|
||||
endpoint to get the user ID that owns the access token. Token refreshing and
|
||||
revocation proceed as with the [login flow](#login-flow).
|
||||
|
||||
#### Token refresh flow
|
||||
|
||||
Refreshing a token with the OAuth 2.0 API should be done with the [refresh token
|
||||
|
|
@ -2203,6 +2356,7 @@ The client must also have obtained a `client_id` by [registering with the server
|
|||
|
||||
This specification supports the following grant types:
|
||||
- [Authorization code grant](#authorization-code-grant)
|
||||
- {{% added-in v="1.18" %}} [Device authorization grant](#device-authorization-grant)
|
||||
- [Refresh token grant](#refresh-token-grant)
|
||||
|
||||
##### Authorization code grant
|
||||
|
|
@ -2240,6 +2394,35 @@ Whether the homeserver supports this parameter is advertised by the
|
|||
Servers that support this parameter SHOULD show the account registration UI in
|
||||
the browser.
|
||||
|
||||
##### Device authorization grant
|
||||
|
||||
{{% added-in v="1.18" %}}
|
||||
|
||||
As per [RFC 8628](https://datatracker.ietf.org/doc/html/rfc8628), the device
|
||||
authorization grant lets clients on devices with limited input capabilities
|
||||
obtain an access token by having the user complete authorization on a separate
|
||||
device with a web browser.
|
||||
|
||||
This grant requires the client to know the following [authorization server
|
||||
metadata](#server-metadata-discovery):
|
||||
|
||||
- `device_authorization_endpoint`
|
||||
|
||||
To use this grant, homeservers and clients MUST:
|
||||
|
||||
- Support the device authorization grant as per
|
||||
[RFC 8628](https://datatracker.ietf.org/doc/html/rfc8628).
|
||||
- Support the [refresh token grant](#refresh-token-grant).
|
||||
|
||||
As with the [authorization code grant](#authorization-code-grant), when
|
||||
authorization is granted to a client, the homeserver MUST issue a refresh token
|
||||
to the client in addition to the access token. The access token and refresh
|
||||
token have the same lifetime constraints as described in the [refresh token
|
||||
grant](#refresh-token-grant) section.
|
||||
|
||||
The full flow for using this grant is described in the
|
||||
[device authorization flow](#device-authorization-flow).
|
||||
|
||||
##### Refresh token grant
|
||||
|
||||
As per [RFC 6749 section 6](https://datatracker.ietf.org/doc/html/rfc6749#section-6),
|
||||
|
|
|
|||
|
|
@ -67,8 +67,8 @@ paths:
|
|||
type: string
|
||||
format: uri
|
||||
description: |-
|
||||
URL of the token endpoint, necessary to use the authorization code grant and
|
||||
the refresh token grant.
|
||||
URL of the token endpoint, necessary to use the authorization code grant,
|
||||
device authorization grant and the refresh token grant.
|
||||
revocation_endpoint:
|
||||
type: string
|
||||
format: uri
|
||||
|
|
@ -101,6 +101,10 @@ paths:
|
|||
This array MUST contain at least the `authorization_code` and `refresh_token`
|
||||
values, for clients to be able to use the authorization code grant and refresh
|
||||
token grant, respectively.
|
||||
|
||||
{{% added-in v="1.18" %}} It MAY also contain
|
||||
`urn:ietf:params:oauth:grant-type:device_code` to indicate support for the
|
||||
[device authorization grant](/client-server-api/#device-authorization-grant).
|
||||
items:
|
||||
type: string
|
||||
description: A grant type that the server supports.
|
||||
|
|
@ -165,6 +169,14 @@ paths:
|
|||
- "org.matrix.account_deactivate"
|
||||
- "org.matrix.cross_signing_reset"
|
||||
description: An action that the account management URL supports.
|
||||
device_authorization_endpoint:
|
||||
x-addedInMatrixVersion: "1.18"
|
||||
type: string
|
||||
format: uri
|
||||
description: |-
|
||||
URL of the device authorization endpoint, as defined in
|
||||
[RFC 8628](https://datatracker.ietf.org/doc/html/rfc8628), necessary to use
|
||||
the [device authorization grant](/client-server-api/#device-authorization-grant).
|
||||
required:
|
||||
- issuer
|
||||
- authorization_endpoint
|
||||
|
|
@ -180,9 +192,10 @@ paths:
|
|||
"authorization_endpoint": "https://account.example.com/oauth2/auth",
|
||||
"token_endpoint": "https://account.example.com/oauth2/token",
|
||||
"registration_endpoint": "https://account.example.com/oauth2/clients/register",
|
||||
"device_authorization_endpoint": "https://account.example.com/oauth2/device",
|
||||
"revocation_endpoint": "https://account.example.com/oauth2/revoke",
|
||||
"response_types_supported": ["code"],
|
||||
"grant_types_supported": ["authorization_code", "refresh_token"],
|
||||
"grant_types_supported": ["authorization_code", "refresh_token", "urn:ietf:params:oauth:grant-type:device_code"],
|
||||
"response_modes_supported": ["query", "fragment"],
|
||||
"code_challenge_methods_supported": ["S256"],
|
||||
"account_management_uri": "https://account.example.com/manage",
|
||||
|
|
|
|||
Loading…
Reference in a new issue