Merge 68184aac31 into e9f0f31d27
commit
d2e96c5d8c
@ -0,0 +1,178 @@
|
|||||||
|
# MSC4341: Support for RFC 8628 Device Authorization Grant
|
||||||
|
|
||||||
|
The current [OAuth 2.0 API](https://spec.matrix.org/v1.15/client-server-api/#oauth-20-api) requires the user to complete
|
||||||
|
authentication using a web browser on the device where the Matrix client is running.
|
||||||
|
|
||||||
|
This can be problematic if the device does not have a built in web browser or the user wishes to use a different device.
|
||||||
|
It also causes issues in scenarios where catching the redirect back to the client is hard, like in CLI apps, or
|
||||||
|
desktop apps with no redirect custom schemes.
|
||||||
|
|
||||||
|
[RFC 8628](https://datatracker.ietf.org/doc/html/rfc8628) defines the OAuth 2.0 Device Authorization Grant which can be
|
||||||
|
used for this purpose.
|
||||||
|
|
||||||
|
## Proposal
|
||||||
|
|
||||||
|
Add the [RFC 8628 OAuth 2.0 Device Authorization Grant](https://datatracker.ietf.org/doc/html/rfc8628) to the [list of supported
|
||||||
|
grant types](https://spec.matrix.org/v1.15/client-server-api/#grant-types) in the Client-Server API.
|
||||||
|
|
||||||
|
This grant requires the client to know the following authorization server metadata:
|
||||||
|
|
||||||
|
- `grant_types_supported` - this would include `urn:ietf:params:oauth:grant-type:device_code`
|
||||||
|
- `device_authorization_endpoint` - this would be added to the [table of fields for the 200 response](https://spec.matrix.org/v1.15/client-server-api/#server-metadata-discovery)
|
||||||
|
- `token_endpoint` - this is already included in the spec
|
||||||
|
|
||||||
|
To use this grant, homeservers and clients MUST:
|
||||||
|
|
||||||
|
- Support the device authorization grant as per RFC 8628.
|
||||||
|
- Support the refresh token grant.
|
||||||
|
|
||||||
|
The [login flow section](https://spec.matrix.org/v1.15/client-server-api/#login-flow) would need to be updated to
|
||||||
|
reflect that more than one login grant type exists.
|
||||||
|
|
||||||
|
As with the existing 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 should have the same lifetime constraints as described for the authorization
|
||||||
|
code grant in the current [spec](https://spec.matrix.org/v1.15/client-server-api/#refresh-token-grant).
|
||||||
|
|
||||||
|
### Sample flow
|
||||||
|
|
||||||
|
The user wishes to login to a Matrix client on a device that doesn't have a web browser built in (e.g. a TV), but wishes
|
||||||
|
to complete the login on another device (e.g. a smartphone).
|
||||||
|
|
||||||
|
1. The Matrix client [discovers the OAuth 2.0 server metadata](https://spec.matrix.org/v1.15/client-server-api/#server-metadata-discovery).
|
||||||
|
|
||||||
|
This step is as per the current Matrix spec, but as per [RFC 8628 section 4](https://datatracker.ietf.org/doc/html/rfc8628#section-4)
|
||||||
|
it should include the value `urn:ietf:params:oauth:grant-type:device_code` in the `grant_types_supported` field and specify
|
||||||
|
a `device_authorization_endpoint` field.
|
||||||
|
|
||||||
|
2. The Matrix client [registers itself as a client with the homeserver](https://spec.matrix.org/v1.15/client-server-api/#client-registration).
|
||||||
|
|
||||||
|
This step is as per the current Matrix spec.
|
||||||
|
|
||||||
|
3. The Matrix client sends a Device Authorization Request to the `device_authorization_endpoint` as per [RFC 8628 section 3.1](https://datatracker.ietf.org/doc/html/rfc8628#section-3.1).
|
||||||
|
|
||||||
|
The `client_id` should be as per the registration step above, and the `scope` as described in the current [spec](https://spec.matrix.org/v1.15/client-server-api/#scope).
|
||||||
|
|
||||||
|
e.g.
|
||||||
|
|
||||||
|
```http
|
||||||
|
POST /oauth2/device HTTP/1.1
|
||||||
|
Host: account.matrix.org
|
||||||
|
Content-Type: application/x-www-form-urlencoded
|
||||||
|
|
||||||
|
client_id=my_client_id&scope=urn%3Amatrix%3Aclient%3Aapi%3A%2A%20urn%3Amatrix%3Aclient%3Adevice%3AABCDEGH
|
||||||
|
```
|
||||||
|
|
||||||
|
4. The homeserver responds to the Matrix client with the Device Authorization Response as per [RFC 8628 section 3.2](https://datatracker.ietf.org/doc/html/rfc8628#section-3.2).
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
```http
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"device_code": "GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS",
|
||||||
|
"user_code": "WDJB-MJHT",
|
||||||
|
"verification_uri": "https://account.matrix.org/link",
|
||||||
|
"verification_uri_complete": "https://account.matrix.org/link?user_code=WDJB-MJHT",
|
||||||
|
"expires_in": 1800,
|
||||||
|
"interval": 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`.
|
||||||
|
|
||||||
|
5. The Matrix client device conveys the returned `verification_uri_complete` (and/or `verification_uri`+`user_code`) to
|
||||||
|
the user.
|
||||||
|
|
||||||
|
Exactly how the client does this depends on the specific device characteristics and use case.
|
||||||
|
|
||||||
|
For example, for a CLI application the `verification_uri` and `user_code` could be displayed as text for the user to
|
||||||
|
type into their other device.
|
||||||
|
|
||||||
|
Or, another example would be the `verification_uri_complete` (with fallback to the `verification_uri`) could be encoded
|
||||||
|
and displayed as a QR code for scanning on the other device (e.g. on a TV).
|
||||||
|
|
||||||
|
6. The user opens the `verification_uri_complete` (or `verification_uri`) on their other device that has a web browser.
|
||||||
|
|
||||||
|
The user then completes authentication and authorization for the login.
|
||||||
|
|
||||||
|
7. Whilst the user is doing this, the Matrix client starts polling the `token_endpoint` for an outcome.
|
||||||
|
|
||||||
|
Frequency of polling is determined by the `interval` value returned in the Device Authorization Response from step 4.
|
||||||
|
|
||||||
|
The poll request made by the client is the Device Access Token Request from [RFC 8628 section 3.4](https://datatracker.ietf.org/doc/html/rfc8628#section-3.4).
|
||||||
|
|
||||||
|
e.g.
|
||||||
|
|
||||||
|
```http
|
||||||
|
POST /oauth2/token HTTP/1.1
|
||||||
|
Host: account.matrix.org
|
||||||
|
Content-Type: application/x-www-form-urlencoded
|
||||||
|
|
||||||
|
grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code&device_code=GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS&client_id=my_client_id
|
||||||
|
```
|
||||||
|
|
||||||
|
The server in turn responds with the Device Access Token Response as per [RFC 8628 section 3.5](https://datatracker.ietf.org/doc/html/rfc8628#section-3.5).
|
||||||
|
|
||||||
|
Whilst the authorization is still outstanding a `authorization_pending` (or `slow_down` in the case of rate limiting)
|
||||||
|
error code will be returned.
|
||||||
|
|
||||||
|
If the authorization is rejected then the `access_denied` error code will be returned.
|
||||||
|
|
||||||
|
If the authorization does not complete within the `expires_in` timeframe then the `expired_token` error code will be returned.
|
||||||
|
|
||||||
|
For a successful authorization the response will be an access token and refresh token as described in the current Matrix
|
||||||
|
[spec](https://spec.matrix.org/v1.15/client-server-api/#login-flow).
|
||||||
|
|
||||||
|
8. The Matrix client refreshes the access token with the refresh token grant when it expires.
|
||||||
|
|
||||||
|
This is as per the current spec.
|
||||||
|
|
||||||
|
9. The Matrix client revokes the tokens when the users wants to log out of the client.
|
||||||
|
|
||||||
|
This is as per the current spec.
|
||||||
|
|
||||||
|
## Potential issues
|
||||||
|
|
||||||
|
Some literature refers to the Device Authorization Grant as the
|
||||||
|
[Device Code](https://oauth.net/2/grant-types/device-code/) grant type or [Device Flow](https://curity.io/resources/learn/oauth-device-flow/).
|
||||||
|
This MSC uses the name from the actual RFC.
|
||||||
|
|
||||||
|
Otherwise, none identified.
|
||||||
|
|
||||||
|
## Alternatives
|
||||||
|
|
||||||
|
I'm not aware of any other standardised OAuth grant types that would be suitable as an alternative.
|
||||||
|
|
||||||
|
### Requiring support for the new grant type
|
||||||
|
|
||||||
|
We could make it mandatory that new grant type is supported by Matrix homeservers.
|
||||||
|
|
||||||
|
As currently proposed it is optional and discoverable via the `grant_types_supported` metadata.
|
||||||
|
|
||||||
|
### Make `verification_uri_complete` be mandatory
|
||||||
|
|
||||||
|
RFC 8628 makes makes `verification_uri_complete` optional, but we could make it mandatory. This could improve the UX for some
|
||||||
|
use cases.
|
||||||
|
|
||||||
|
## Security considerations
|
||||||
|
|
||||||
|
[RFC 8628 section 5](https://datatracker.ietf.org/doc/html/rfc8628#section-5) contains various security considerations
|
||||||
|
that homeserver and client implementors should consider.
|
||||||
|
|
||||||
|
Additionally, [RFC 9700](https://datatracker.ietf.org/doc/html/rfc9700) Best Current Practice for OAuth 2.0 Security
|
||||||
|
mentions clickjacking as a consideration for the server and advises on appropriate measures.
|
||||||
|
|
||||||
|
## Unstable prefix
|
||||||
|
|
||||||
|
Although the response from the server metadata discovery endpoint is modified, because
|
||||||
|
[we already defined it](https://spec.matrix.org/v1.15/client-server-api/#get_matrixclientv1auth_metadata) as being
|
||||||
|
[RFC 8414](https://datatracker.ietf.org/doc/html/rfc8414) it isn't appropriate to introduce unstable prefixes.
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
None.
|
||||||
Loading…
Reference in New Issue