linagora / tmail-backend

GNU Affero General Public License v3.0
41 stars 22 forks source link

Secure authentication (mobile) #207

Closed chibenwa closed 3 years ago

chibenwa commented 3 years ago

CF https://github.com/linagora/tmail-flutter/issues/28

TMail backend offers better option

GIVEN the user never used the app
THEN the user is prompted for the URL / login / password

The first call is done with basic authentication to get the session (credential are so far kept in memory on the device side)

If the session contains the com:linagora:long:lived:token then the client does a second call (authenticated with basic auth):

[ "LongLiveToken/set",
   { "create": {
      "accountId":"erivgeruferf",
       "clientId": "My android device"
       }
    }, "#0"
]`

Will return :

[ "LongLiveToken/set",
   { "created": {
       "id": "whatever",
       "token": "xxxyyyzzz"
       }
    }, "#0"
]

TMail mobile then stores this long lived token. Given that token, TMail will not need user input upon connection.

This long lived token can be used to generate short lived JWT token that can be used for auth.

Example:

GET /token?type=shortLived&deviceId=xxxx

Authorization: bearer xxxyyyzzz
(note: here only the long lived token and basic auth can be used as a bearer )
(note: basic auth support enpowers secure web access, as in a browser storing long lived tokens is a bad practice...
    allowing basic auth here would allow web clients to create short lived tokens straight after the auth form
    of course, the use of basic auth here is of no use to the mobile team... When using basic auth, device id is ignored 
    and can be missing)

Will return:

{ 
   "token": "aaaaabbbbccccc",
   "expiresOn": "2020-08-17T11:39:40.906+07:00"
}

(if the device id matches, fails otherwise) - (also please note that this token will need to be frequently renewed ;-) frequent renewal enforce security.)

And follow up requests can be done with:

Authorization: Bearer aaaaabbbbccccc
(note: here long lived token usage is REJECTED)

Note that one:

Eg:

[ "LongLiveToken/get",
   { 
      "accountId":"erivgeruferf"
    }, "#0"
]`

Will return :


[ "LongLiveToken/get",
   {
      "accountId":"erivgeruferf"
      "list": [
       {
       "id": "1",
       "clientId": "My android device"
       },
       {
       "id": "2",
       "clientId": "My IOS device"
       }
    }, "#0"
]`

To revoke access to my IOS device:

[ "LongLiveToken/set",
   { 
      "accountId":"erivgeruferf",
      "destroy": ["2"]
    }, "#0"
]`

And again, if the account do not support this extension, we NEED to support basic authentication.

chibenwa commented 3 years ago

Issues:

chibenwa commented 3 years ago

TODO write an ADR for TMail

chibenwa commented 3 years ago

See https://github.com/linagora/james-project-private/pull/226 for the ADR

chibenwa commented 3 years ago

Flow details

Authentication against a TMail server (first connection)

Authentication against a TMail server (later connections)

Authentication against a regular JMAP server (first connection)

Authentication against a regular JMAP server (later connections)

Web authentication against a regular JMAP server

Use of basic authentication.