diff --git a/api/client-server/cas_login_redirect.yaml b/api/client-server/cas_login_redirect.yaml new file mode 100644 index 00000000..7a4cec5d --- /dev/null +++ b/api/client-server/cas_login_redirect.yaml @@ -0,0 +1,53 @@ +# Copyright 2016 OpenMarket Ltd +# +# 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. +swagger: '2.0' +info: + title: "Matrix Client-Server CAS Login API" + version: "1.0.0" +host: localhost:8008 +schemes: + - https + - http +basePath: /_matrix/client/%CLIENT_MAJOR_VERSION% +paths: + "/login/cas/redirect": + get: + summary: Redirect the user's browser to the CAS interface. + description: |- + A web-based Matrix client should instruct the user's browser to + navigate to this endpoint in order to log in via CAS. + + The server MUST respond with an HTTP redirect to the CAS interface. The + URI MUST include a ``service`` parameter giving the path of the + |/login/cas/ticket|_ endpoint (including the ``redirectUrl`` query + parameter). + + For example, if the endpoint is called with + ``redirectUrl=https://client.example.com/?q=p``, it might redirect to + ``https://cas.example.com/?service=https%3A%2F%2Fserver.example.com%2F_matrix%2Fclient%2F%CLIENT_MAJOR_VERSION%%2Flogin%2Fcas%2Fticket%3FredirectUrl%3Dhttps%253A%252F%252Fclient.example.com%252F%253Fq%253Dp``. + + parameters: + - in: query + type: string + name: redirectUrl + description: |- + URI to which the user will be redirected after the homeserver has + authenticated the user with CAS. + required: true + responses: + 302: + description: A redirect to the CAS interface. + headers: + Location: + type: "string" diff --git a/api/client-server/cas_login_ticket.yaml b/api/client-server/cas_login_ticket.yaml new file mode 100644 index 00000000..02469489 --- /dev/null +++ b/api/client-server/cas_login_ticket.yaml @@ -0,0 +1,65 @@ +# Copyright 2016 OpenMarket Ltd +# +# 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. +swagger: '2.0' +info: + title: "Matrix Client-Server CAS Login API" + version: "1.0.0" +host: localhost:8008 +schemes: + - https + - http +basePath: /_matrix/client/%CLIENT_MAJOR_VERSION% +paths: + "/login/cas/ticket": + get: + summary: Receive and validate a CAS login ticket. + description: |- + Once the CAS server has authenticated the user, it will redirect the + browser to this endpoint (assuming |/login/cas/redirect|_ gave it the + correct ``service`` parameter). + + The server MUST call ``/proxyValidate`` on the CAS server, to validate + the ticket supplied by the browser. + + If validation is successful, the server must generate a Matrix login + token. It must then respond with an HTTP redirect to the URI given in + the ``redirectUrl`` parameter, adding a ``loginToken`` query parameter + giving the generated token. + + If validation is unsuccessful, the server should respond with a ``401 + Unauthorized`` error, the body of which will be displayed to the user. + parameters: + - in: query + type: string + name: redirectUrl + description: |- + The ``redirectUrl`` originally provided by the client to + |/login/cas/redirect|_. + required: true + - in: query + type: string + name: ticket + description: |- + CAS authentication ticket. + required: true + responses: + 302: + description: A redirect to the Matrix client. + headers: + Location: + type: "string" + x-example: |- + https://client.example.com/?q=p&loginToken=secrettoken + 401: + description: The server was unable to validate the CAS ticket. diff --git a/api/client-server/login.yaml b/api/client-server/login.yaml index 34b33cf3..3ca397ea 100644 --- a/api/client-server/login.yaml +++ b/api/client-server/login.yaml @@ -47,7 +47,8 @@ paths: properties: type: type: string - description: The login type being used. Currently only "m.login.password" is supported. + enum: ["m.login.password", "m.login.token"] + description: The login type being used. user: type: string description: The fully qualified user ID or just local part of the user ID, to log in. @@ -59,8 +60,14 @@ paths: description: Third party identifier for the user. password: type: string - description: The user's password. - required: ["type", "password"] + description: |- + Required when ``type`` is ``m.login.password``. The user's + password. + token: + type: string + description: |- + Required when ``type`` is ``m.login.token``. The login token. + required: ["type"] responses: 200: diff --git a/changelogs/client_server.rst b/changelogs/client_server.rst index 8d903cd0..40d5d764 100644 --- a/changelogs/client_server.rst +++ b/changelogs/client_server.rst @@ -14,6 +14,8 @@ - Add ``filename`` parameter to ``POST /_matrix/media/r0/upload`` (`#364 `_). + - Document CAS-based client login and the use of ``m.login.token`` in + ``/login`` (`#367 `_). r0.2.0 diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 9a342413..fb140c22 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -407,7 +407,7 @@ Token-based :Type: ``m.login.token`` :Description: - The client submits a username and token. + The client submits a login token. To respond to this type, reply with an auth dict as follows: @@ -415,7 +415,6 @@ To respond to this type, reply with an auth dict as follows: { "type": "m.login.token", - "user": "", "token": "", "txn_id": "" } @@ -433,7 +432,8 @@ server side, as well as potentially invalidating the token completely once the device has successfully logged in (e.g. when we receive a request from the newly provisioned access_token). -The ``token`` must be a macaroon. +The ``token`` must be a macaroon, with a caveat encoding the user id. There is +therefore no need for the client to submit a separate username. OAuth2-based <<<<<<<<<<<< @@ -552,7 +552,20 @@ explicitly, as follows: } In the case that the homeserver does not know about the supplied 3pid, the -homeserver must respond with 403 Forbidden. +homeserver must respond with ``403 Forbidden``. + +To log in using a login token, a client should submit an auth dict as follows: + +.. code:: json + + { + "type": "m.login.token", + "token": "" + } + +As with `token-based`_ interactive login, the ``token`` must be a macroon with +a caveat which includes the user id. In the case that the token is not valid, the +homeserver must respond with ``403 Forbidden`` and an error code of ``M_FORBIDDEN``. {{login_cs_http_api}} diff --git a/specification/modules/cas_login.rst b/specification/modules/cas_login.rst new file mode 100644 index 00000000..4c3b826a --- /dev/null +++ b/specification/modules/cas_login.rst @@ -0,0 +1,119 @@ +.. Copyright 2016 OpenMarket Ltd +.. +.. 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. + +CAS-based client login +====================== + +.. _module:cas_login: + +`Central Authentication Service +`_ +(CAS) is a web-based single sign-on protocol. + +An overview of the process, as used in Matrix, is as follows: + +1. The Matrix client instructs the user's browser to navigate to the + |/login/cas/redirect|_ endpoint on the user's homeserver. + +2. The homeserver responds with an HTTP redirect to the CAS user interface, + which the browser follows. + +3. The CAS system authenticates the user. + +4. The CAS server responds to the user's browser with a redirect back to the + |/login/cas/ticket|_ endpoint on the homeserver, which the browser + follows. A 'ticket' identifier is passed as a query parameter in the + redirect. + +5. The homeserver receives the ticket ID from the user's browser, and makes a + request to the CAS server to validate the ticket. + +6. Having validated the ticket, the homeserver responds to the browser with a + third HTTP redirect, back to the Matrix client application. A login token + is passed as a query parameter in the redirect. + +7. The Matrix client receives the login token and passes it to the |/login|_ + API. + +Client behaviour +---------------- + +The client starts the process by instructing the browser to navigate to +|/login/cas/redirect|_ with an appropriate ``redirectUrl``. Once authentication +is successful, the browser will be redirected to that ``redirectUrl``. + +.. TODO-spec + + Should we recommend some sort of CSRF protection here (specifically, we + should guard against people accidentally logging in by sending them a link + to ``/login/cas/redirect``. + + Maybe we should recommend that the ``redirectUrl`` should contain a CSRF + token which the client should then check before sending the login token to + ``/login``? + +{{cas_login_redirect_cs_http_api}} +{{cas_login_ticket_cs_http_api}} + +Server behaviour +---------------- + +The URI for the CAS system to be used should be configured on the server by the +server administrator. + +Handling the redirect endpoint +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When responding to the ``/login/cas/redirect`` endpoint, the server must +generate a URI for the CAS login page. The server should take the base CAS URI +described above, and add a ``service`` query parameter. This parameter MUST be +the URI of the ``/login/cas/ticket`` endpoint, including the ``redirectUrl`` +query parameter. Because the homeserver may not know its base URI, this may +also require manual configuration. + +.. TODO-spec: + + It might be nice if the server did some validation of the ``redirectUrl`` + parameter, so that we could check that aren't going to redirect to a non-TLS + endpoint, and to give more meaningful errors in the case of + faulty/poorly-configured clients. + +Handling the authentication endpoint +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When responding to the ``/login/cas/ticket`` endpoint, the server MUST make a +request to the CAS server to validate the provided ticket. The server MAY also +check for certain user attributes in the response. Any required attributes +should be configured by the server administrator. + +Once the ticket has been validated, the server MUST map the CAS ``user_id`` +to a valid `Matrix user identifier <../intro.html#user-identifiers>`_. The +guidance in `Mapping from other character sets +<../intro.html#mapping-from-other-character-sets>`_ may be useful. + +If the generated user identifier represents a new user, it should be registered +as a new user. + +Finally, the server should generate a short-term login token. The generated +token should be a macaroon, suitable for use with the ``m.login.token`` type of +the |/login|_ API, and `token-based interactive login <#token-based>`_. The +lifetime of this token SHOULD be limited to around five seconds. + + +.. |/login| replace:: ``/login`` +.. _/login: #post-matrix-client-%CLIENT_MAJOR_VERSION%-login +.. |/login/cas/redirect| replace:: ``/login/cas/redirect`` +.. _/login/cas/redirect: #get-matrix-client-%CLIENT_MAJOR_VERSION%-login-cas-redirect +.. |/login/cas/ticket| replace:: ``/login/cas/ticket`` +.. _/login/cas/ticket: #get-matrix-client-%CLIENT_MAJOR_VERSION%-login-cas-ticket diff --git a/specification/targets.yaml b/specification/targets.yaml index d759a7e8..6cbfa917 100644 --- a/specification/targets.yaml +++ b/specification/targets.yaml @@ -52,6 +52,7 @@ groups: # reusable blobs of files when prefixed with 'group:' - modules/account_data.rst - modules/admin.rst - modules/event_context.rst + - modules/cas_login.rst title_styles: ["=", "-", "~", "+", "^", "`", "@", ":"]