diff --git a/changelogs/client_server/newsfragments/3163.feature b/changelogs/client_server/newsfragments/3163.feature new file mode 100644 index 00000000..8595394f --- /dev/null +++ b/changelogs/client_server/newsfragments/3163.feature @@ -0,0 +1 @@ +Multiple SSO providers are possible through `m.login.sso` as per [MSC2858](https://github.com/matrix-org/matrix-doc/pull/2858). \ No newline at end of file diff --git a/changelogs/client_server/newsfragments/3163.new b/changelogs/client_server/newsfragments/3163.new new file mode 100644 index 00000000..ba41fd8d --- /dev/null +++ b/changelogs/client_server/newsfragments/3163.new @@ -0,0 +1 @@ +`/login/sso/redirect/{idpId}` has been added as per [MSC2858](https://github.com/matrix-org/matrix-doc/pull/2858). \ No newline at end of file diff --git a/content/client-server-api/modules/sso_login.md b/content/client-server-api/modules/sso_login.md index eb6a0bb9..2bc3916b 100644 --- a/content/client-server-api/modules/sso_login.md +++ b/content/client-server-api/modules/sso_login.md @@ -39,6 +39,10 @@ authentication the homeserver should provide a means for the administrator to configure where the CAS server is and the REST endpoints which consume the ticket. +Homeservers may optionally expose multiple possible SSO options for +the user to pursue, typically in the form of several "log in with $provider" +buttons. These are known as "identity providers" (IdPs). + #### Client login via SSO An overview of the process is as follows: @@ -49,6 +53,8 @@ An overview of the process is as follows: 2. To initiate the `m.login.sso` login type, the Matrix client instructs the user's browser to navigate to the [`/login/sso/redirect`](/client-server-api/#get_matrixclientr0loginssoredirect) endpoint on the user's homeserver. + Note that this may be the IdP-dependent version of the endpoint if the + user has selected one of the `identity_providers` from the flow. 3. The homeserver responds with an HTTP redirect to the SSO user interface, which the browser follows. 4. The authentication server and the homeserver interact to verify the @@ -97,10 +103,15 @@ endpoint to use: for `m.login.cas`, use `/cas/redirect` and for otherwise the same. {{% /boxes/note %}} +{{% definition path="api/client-server/definitions/sso_login_flow" %}} + ##### Client behaviour The client starts the process by instructing the browser to navigate to -[`/login/sso/redirect`](/client-server-api/#get_matrixclientr0loginssoredirect) with an appropriate `redirectUrl`. Once +[`/login/sso/redirect`](/client-server-api/#get_matrixclientr0loginssoredirect) +(or [`/login/sso/redirect/{idpId}`](/client-server-api/#get_matrixclientr0loginssoredirectidpid) +when using one of the `identity_providers`) +with an appropriate `redirectUrl`. Once authentication is successful, the browser will be redirected to that `redirectUrl`. @@ -141,6 +152,10 @@ authentication is successful, the browser will be redirected to that ##### Server behaviour +Servers should note that `identity_providers` are optional, and older clients +might not interpret the value correctly. In these cases, the client will use +the generic `/redirect` endpoint instead of the `/redirect/{idpId}` endpoint. + ###### Redirecting to the Authentication server The server should handle diff --git a/data/api/client-server/definitions/sso_login_flow.yaml b/data/api/client-server/definitions/sso_login_flow.yaml new file mode 100644 index 00000000..0dd011b3 --- /dev/null +++ b/data/api/client-server/definitions/sso_login_flow.yaml @@ -0,0 +1,82 @@ +# Copyright 2021 The Matrix.org Foundation C.I.C. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +type: object +title: m.login.sso flow schema +properties: + type: + type: enum + enum: ["m.login.sso"] + description: The string `m.login.sso` + example: "m.login.sso" + identity_providers: + type: array + description: |- + Optional identity providers (IdPs) to present to the user. These would + appear (typically) as distinct buttons for the user to interact with, + and would map to the appropriate IdP-dependent redirect endpoint for that + IdP. + example: [ + {"id": "com.example.idp.github", "name": "GitHub", "brand": "github"}, + {"id": "com.example.idp.gitlab", "name": "GitLab", "icon": "mxc://example.com/abc123"}, + ] + items: + type: object + title: IdP + description: An identity provider. + properties: + id: + type: string + description: |- + Opaque string chosen by the homeserver, uniquely identifying + the IdP from other IdPs the homeserver might support. Should + be between 1 and 255 characters in length, containing unreserved + characters under [RFC 3986](http://www.ietf.org/rfc/rfc3986.txt) + (`ALPHA DIGIT "-" / "." / "_" / "~"`). Clients are not intended + to parse or infer meaning from opaque strings. + example: "com.example.idp.github" + name: + type: string + description: |- + Human readable description for the IdP, intended to be shown to + the user. + example: "Github" + icon: + type: string + description: |- + Optional MXC URI to provide an image/icon representing the IdP. + Intended to be shown alongside the `name` if provided. + example: "mxc://example.org/abc123" + brand: + type: string + # TODO @@TR: Actually link to "common identifier format" section when it exists. + description: |- + Optional UI hint for what kind of common SSO provider is being + described in this IdP. Matrix maintains a registry of identifiers + [in the matrix-doc repo](https://github.com/matrix-org/matrix-doc/blob/master/informal/idp-brands.md) + to ensure clients and servers are aligned on major/common brands. + + Clients should prefer the `brand` over the `icon`, when both are + provided. Clients are not required to support any particular `brand`, + including those in the registry, though are expected to be able to + present any IdP based off the `name`/`icon` to the user regardless. + + Unregistered brands are permitted using the Standard Identifier Format, + though excluding the namespace requirements. For example, `examplesso` + is a valid brand which is not in the registry but still permitted. + Servers should be mindful that clients might not support their unregistered + brand usage as intended by the server. + example: "github" + required: ['id', 'name'] + +required: ['type'] diff --git a/data/api/client-server/sso_login_redirect.yaml b/data/api/client-server/sso_login_redirect.yaml index acbafc57..8c92a3ce 100644 --- a/data/api/client-server/sso_login_redirect.yaml +++ b/data/api/client-server/sso_login_redirect.yaml @@ -28,7 +28,9 @@ paths: A web-based Matrix client should instruct the user's browser to navigate to this endpoint in order to log in via SSO. - The server MUST respond with an HTTP redirect to the SSO interface. + The server MUST respond with an HTTP redirect to the SSO interface, + or present a page which lets the user select an IdP to continue + with in the event multiple are supported by the server. operationId: redirectToSSO parameters: - in: query @@ -44,3 +46,40 @@ paths: headers: Location: type: "string" + "/login/sso/redirect/{idpId}": + get: + summary: Redirect the user's browser to the SSO interface for an IdP. + description: |- + This endpoint is the same as `/login/sso/redirect`, though with an + IdP ID from the original `identity_providers` array to inform the + server of which IdP the client/user would like to continue with. + + The server MUST respond with an HTTP redirect to the SSO interface + for that IdP. + operationId: redirectToSSO + parameters: + - in: path + type: string + name: idpId + required: true + description: |- + The `id` of the IdP from the `m.login.sso` `identity_providers` + array denoting the user's selection. + - in: query + type: string + name: redirectUrl + description: |- + URI to which the user will be redirected after the homeserver has + authenticated the user with SSO. + required: true + responses: + 302: + description: A redirect to the SSO interface. + headers: + Location: + type: "string" + 404: + description: |- + The IdP ID was not recognized by the server. The server is encouraged + to provide a user-friendly page explaining the error given the user + will be navigated to it. diff --git a/informal/idp-brands.md b/informal/idp-brands.md new file mode 100644 index 00000000..24f91811 --- /dev/null +++ b/informal/idp-brands.md @@ -0,0 +1,67 @@ +# SSO IdP brand registry + +This informal document contains specification for common brands that clients might experience +in the wild as part of `m.login.sso` flows. To add your brand, open a PR against this document +with the relevant additions (using the existing specification as reference) - an MSC is not +required. Once opened, mention your PR in [#sct-office:matrix.org](https://matrix.to/#/#sct-office:matrix.org) +on Matrix so it doesn't end up lost. + +Please also take some time to read the [contributing guidelines](https://github.com/matrix-org/matrix-doc/blob/master/CONTRIBUTING.rst) +for an overview of PR requirements. + + + +## Brands + +For the brands listed here, the `identifier` would be used as the `brand` value in an IdP definition +under `m.login.sso`'s flow. + +Note that each brand may have their own requirements for how they are represented by clients, such as +Facebook/Twitter wanting their signature blues for button backgrounds whereas GitHub is not as particular +about the press requirements. Clients should not rely on this document for guidance on press requirements +and instead refer to the brands individually. + + +### Apple + +**Identifier**: `apple` + +Suitable for "Sign in with Apple": see https://developer.apple.com/design/human-interface-guidelines/sign-in-with-apple/overview/buttons/. + + +### Facebook + +**Identifier**: `facebook` + +"Continue with Facebook": see https://developers.facebook.com/docs/facebook-login/web/login-button/. + + +### GitHub + +**Identifier**: `github` + +Logos available at https://github.com/logos. + + +### GitLab + +**Identifier**: `gitlab` + +Logos available at https://about.gitlab.com/press/press-kit/. + + +### Google + +**Identifier**: `google` + +Suitable for "Google Sign-In": see https://developers.google.com/identity/branding-guidelines. + + +### Twitter + +**Identifier**: `twitter` + +Suitable for "Log in with Twitter": see https://developer.twitter.com/en/docs/authentication/guides/log-in-with-twitter#tab1.