From 18b2bf381a2146fd5a6214599f876e184db57f47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20HUBSCHER?= Date: Tue, 23 Dec 2014 17:52:45 +0100 Subject: [PATCH 1/2] Add an article about adding Firefox Account integration for Daybed. --- content/services/fxa-oauth-integration.rst | 106 +++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 content/services/fxa-oauth-integration.rst diff --git a/content/services/fxa-oauth-integration.rst b/content/services/fxa-oauth-integration.rst new file mode 100644 index 0000000..8c33928 --- /dev/null +++ b/content/services/fxa-oauth-integration.rst @@ -0,0 +1,106 @@ +How we implemented a Firefox Account OAuth service provider with Cornice +######################################################################## + +:slug: fxa-oauth-integration +:date: 23-12-2014 +:authors: Alexis Métaireau, Rémy Hubscher +:tags: FxA, python +:lang: en + +Daybed is user agnostic, when you logs in you grab an Hawk Token +derives into credentials that are used to sign every request made to +the API. + +This token can then be linked to anything: the user, the device or a +group with share credentials. + +This lets people use daybed the way it fits their software. + +Also when you want user's devices to use the same token, you need a way +to share it. + + +Get a token using Basic-Auth +---------------------------- + +One way to solve this problem, was to let the user give an +Authorization header when asking for a new token. + +And make sure the same token would be generated for the same header. + +This works really well, because you can then use a login:password and +always grab the same Hawk-Credentials for it. + +In a nutshell it looks like this: + +.. code-block:: python + + http POST localhost:8000/v1/tokens --auth admin:password -v + + POST /v1/tokens HTTP/1.1 + Accept: */* + Accept-Encoding: gzip, deflate, compress + Authorization: Basic YWRtaW46cGFzc3dvcmQ= + Content-Length: 0 + Host: localhost:8000 + User-Agent: HTTPie/0.8.0 + + HTTP/1.1 201 Created + Content-Length: 266 + Content-Type: application/json; charset=UTF-8 + Date: Fri, 07 Nov 2014 15:09:01 GMT + Server: waitress + + { + "credentials": { + "algorithm": "sha256", + "id": "371ef18f8a054e5c9fb0961cc5b81006080e9ad22078d30b3727c7c32843579f", + "key": "87e72a8e5dcaf8b4be00b8729462814da3d438ce2fd8b6efee335db722d8369d" + }, + "token": "9f19de0237c9bd59f803de1785f7aea4e3499b6929df3428e1b415fed81f797a" + } + + +Get a token from Firefox Account using OAuth +-------------------------------------------- + +Basic-Auth is good but it means you need to enter your login password +in the client app and trust the usage they will do with it. + +Also for some application you want to trust the email address of the +user. + +One way to do that is to use Firefox Account. The email used has been +validated and the login is made on a trusted Mozilla server. + +The OAuth flow works as defined here: + +1. You access you service ``http://service/oauth/params`` url to get the OAuth configuration in ``conf`` +2. The app redirect the user to:: + + GET conf.oauth_uri + "/authorization?" + + "client_id=" + conf.client_id + + "&state=" + conf.state + + "&scope=profile&action=signin" + +3. The user logs in in the OAuth identity provider +4. After the password has been validated, the OAuth IDP redirect the user to ``http://service//oauth/token?state=&code=`` +5. Then the server ask ``POST conf.oauth_uri + "/token"`` with the ``code``, ``client_id`` and ``client_secret`` to get an ``access_token``. +6. The ``access_token`` can then be used to ask about the user profile: ``GET conf.profile_uri + "/profile"`` with ``Authorization: Bearer `` header. +7. From the profile you can get the ``email``, ``avatar`` and ``uid`` of the user. + + +You have got an example of the view implementations here: https://github.com/spiral-project/daybed-fxa-oauth + +Other authentication backends +----------------------------- + +We have made this Authentication layer a pluggable layer so that you +can deploy Daybed with any of the one you'd like as well as all of +them. + +You have another example for the BrowserID protocol here: https://github.com/spiral-project/daybed-browserid + +You can use it with Persona, Firefox Account BrowserId and even MSISDN-Gateway to let people log using their phone number. + +This plugins can also help you to implement other authentication backends for Daybed. (SAML, other OAuth) From 88866536f0dec6908753fb42c52a34eccb5f0a97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20HUBSCHER?= Date: Wed, 24 Dec 2014 10:28:23 +0100 Subject: [PATCH 2/2] @leplatrem review. --- content/services/fxa-oauth-integration.rst | 37 +++++++++++++++------- 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/content/services/fxa-oauth-integration.rst b/content/services/fxa-oauth-integration.rst index 8c33928..e203e95 100644 --- a/content/services/fxa-oauth-integration.rst +++ b/content/services/fxa-oauth-integration.rst @@ -7,17 +7,23 @@ How we implemented a Firefox Account OAuth service provider with Cornice :tags: FxA, python :lang: en -Daybed is user agnostic, when you logs in you grab an Hawk Token -derives into credentials that are used to sign every request made to -the API. +Daybed is user agnostic. It does not handle users and passwords but +tokens, using Hawk. When you log in, you obtain a Hawk Token derived +into credentials that are used to sign every request made to the API. -This token can then be linked to anything: the user, the device or a -group with share credentials. +This token can then represent anything: the user, the device or a +group of users that share the same token. -This lets people use daybed the way it fits their software. +This lets people use Daybed the way it fits their software. -Also when you want user's devices to use the same token, you need a way -to share it. +But on the other hand, when a user wants to user the same token on all +her devices, she needs a way to share it easily and securely. + +There are several ways to do it, among them: + +- Put the token in the URLs of your applications (like 0bin, doodle, google docs, ...), and share the URLs on your devices using synced bookmarks for example +- Build the token from the authorization header +- Build the token from a user id obtained via OAuth Get a token using Basic-Auth @@ -89,8 +95,12 @@ The OAuth flow works as defined here: 6. The ``access_token`` can then be used to ask about the user profile: ``GET conf.profile_uri + "/profile"`` with ``Authorization: Bearer `` header. 7. From the profile you can get the ``email``, ``avatar`` and ``uid`` of the user. +After the OAuth flow, we generate a token for this user, for the same +Firefox Account, the token will always be the same. + +You have got an example of the view implementations here: +https://github.com/spiral-project/daybed-fxa-oauth -You have got an example of the view implementations here: https://github.com/spiral-project/daybed-fxa-oauth Other authentication backends ----------------------------- @@ -99,8 +109,11 @@ We have made this Authentication layer a pluggable layer so that you can deploy Daybed with any of the one you'd like as well as all of them. -You have another example for the BrowserID protocol here: https://github.com/spiral-project/daybed-browserid +You have another example for the BrowserID protocol here: +https://github.com/spiral-project/daybed-browserid -You can use it with Persona, Firefox Account BrowserId and even MSISDN-Gateway to let people log using their phone number. +You can use it with Persona, Firefox Account BrowserId and even +MSISDN-Gateway to let people log using their phone number. -This plugins can also help you to implement other authentication backends for Daybed. (SAML, other OAuth) +This plugins can also help you to implement other authentication +backends for Daybed. (SAML, other OAuth)