Skip to content

Commit

Permalink
oauth
Browse files Browse the repository at this point in the history
  • Loading branch information
ymarcon committed May 2, 2018
1 parent 7995611 commit 3a469e6
Show file tree
Hide file tree
Showing 10 changed files with 302 additions and 1 deletion.
2 changes: 2 additions & 0 deletions administrator-guide/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Administrator Guide
===================
19 changes: 18 additions & 1 deletion index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,26 @@ Welcome to Agate's documentation!

.. toctree::
:maxdepth: 2
:caption: Contents:
:caption: Contents

presentation/index
administrator-guide/index

.. toctree::
:maxdepth: 2
:caption: User Guides

web-user-guide/index
python-user-guide/index

.. toctree::
:maxdepth: 2
:caption: API

oauth2-api/index
oauth2-api/authorization-code-grant-flow
oauth2-api/resource-owner-password-credentials-grant-flow
oauth2-api/openid-connect-flow

Indices and tables
==================
Expand Down
218 changes: 218 additions & 0 deletions oauth2-api/authorization-code-grant-flow.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
Authorization Code Grant Flow
=============================

Summary
-------

When a client application wants access to the resources of a resource owner, hosted on a resource server, the client application must first obtain an authorization code grant from the authorization server (Agate). The following explains how such a grant is obtained.

Step 1. Authorization
---------------------

Request
~~~~~~~

The client application must redirect the user to the Agate authorization page which is:

.. code-block:: rest
GET https://agate.example.org/ws/oauth2/authorize?<PARAMETERS>
The following values should/could be passed as parameters:

=================== ===================
Parameter Description
=================== ===================
``client_id`` Client application that will be granted the authorization (required).
``response_type`` The expected value is: code (required).
``scope`` Space separated application names (required).
``redirect_uri`` URL to redirect back to (optional, if not specified default client application redirect URI will be used).
``state`` Unique string to be passed back upon completion (optional, recommended).
=================== ===================

Agate will redirect the "user-agent" (usually a web browser) to a web page where the resource owner can grant or deny the requested authorizations.

Response
~~~~~~~~

If the resource owner accepts to grant the requested authorizations to the client application, then the response will consist of a redirect to the provided redirect_uri with the following request parameters:

=================== ===================
Parameter Description
=================== ===================
``code`` The authorization code.
``state`` The state parameter value that was provided in the request (if any).
``expires_in`` Information about the expiration time (in seconds) before the authorization expires.
=================== ===================

The redirect request will then look like:

.. code-block:: rest
GET https://client.example.org/redirect?code=AUTHORIZATION_CODE&state=STATE&expires_in=7775999
From then, it is the responsibility of the client application to response to this request with a redirect to the relevant client application page.

Errors
~~~~~~

The following response errors can be encountered during this step.

.. code-block:: rest
GET https://client.example.org/redirect?error=ERROR_CODE&error_description=ERROR_MESSAGE
==================================== ===================
Parameter Description
==================================== ===================
``access_denied`` When the user refuses to grant the requested authorization.
``invalid_scope`` The requested scope is not one of the declared resource application scopes.
``missing_application_redirect_uri`` The client application does not have a default redirect URI. This is a client application definition issue.
``invalid_redirect_uri`` The provided redirect URI does not starts with the client application's default redirect URI.
``server_error`` Other errors.
==================================== ===================

Step 2. Access Token Issuing
----------------------------

Request
~~~~~~~

The REST endpoint to be used is:

.. code-block:: rest
POST https://agate.example.org/ws/oauth2/token
The form parameters to be sent within the body of the request are:

client_id Client application name (required).
client_secret Client application secret key (required).
grant_type The expected value is: authorization_code (required).
code The authorization code from the Step 1 (required).
redirect_uri Must match the originally submitted URI (if one was sent).

Response
~~~~~~~~

The response is a JSON object with the following properties:

=================== ===================
Property Description
=================== ===================
``access_token`` The access token. Agate provides signed tokens that implement the JSON Web Token specification.
``token_type`` What you can do with this token; in the case of Agate the value for this property is bearer.
``expires_in`` Information about the expiration time (in seconds) before the token expires.
=================== ===================


An example of response would be:

.. code-block:: json
{
"access_token": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJlZGl0b3IiLCJpc3MiOiJhZ2F0ZTo1NmZjMzg0MmNjZjJjMWM3ZWM1YzVkMTQiLCJpYXQiOjE0NTk0NTg0NTgsImV4cCI6MTQ1OTQ4NzI1OCwianRpIjoiNTZmZDkxOWFjY2YyYzFjN2VjNWM1ZDE2IiwiYXVkIjpbIm1pY2EiLCJ0b3RvIl0sImNvbnRleHQiOnsic2NvcGVzIjpbIm1pY2EiXSwidXNlciI6eyJuYW1lIjoiSnVsaWUiLCJncm91cHMiOlsibWljYS1lZGl0b3IiXSwiZmlyc3RfbmFtZSI6Ikp1bGllIn19fQ.PqlLSZegdPLM2byp0jsgWV-XM3Xed8DP4I03kbUUEeo",
"token_type": "bearer",
"expires_in": 28799
}
Being a JSON Web Token (JWT), the access token can be decoded. There are three parts in a JWT: the header, the payload and the signature. This could give for example:

.. code-block:: text
{
"alg": "HS256"
}
.
{
"sub": "editor",
"iss": "agate:56fc3842ccf2c1c7ec5c5d14",
"iat": 1459458458,
"exp": 1459487258,
"jti": "56fd919accf2c1c7ec5c5d16",
"aud": [
"mica",
"client_app"
],
"context": {
"scopes": [
"mica"
],
"user": {
"name": "Julie LaTendresse",
"groups": [
"mica-editor"
],
"first_name": "Julie",
"last_name": "Latendresse"
}
}
}
.
[signature]
The JWT payload contains some basic details on the subject (in addition to the standard claims). These are available in the context object (which is a claim specific to Agate). The properties of the context are:

=================== ===================
Property Description
=================== ===================
``user.name`` The user full name for display.
``user.first_name`` The user first name (if any).
``user.last_name`` The user last name (if any).
``user.groups`` The user groups.
``scopes`` Reminder of the scopes associated to the authorization code grant.
=================== ===================

Note that this step can be repeated as many times as necessary, using the same authorization code that was granted at step 1.

Errors
~~~~~~

When an error is encountered during this step, the JSON object returned contains the description of the error, for example:

.. code-block:: json
{
"error_description":"Authorization with code '3b1d664fb09407972d4c212081789c6f' does not exist",
"error":"NoSuchAuthorizationException"
}
Step 3. Resource Access
-----------------------

The client application will use the access token as a bearer of resource owner identity to get the resource from the resource server. How the access token should be passed to the resource application is out of the concern of Agate.

Most common practice (this is the case for Opal and Mica) is that the access token is placed in the headers of the HTTP request issued by the client application on the resource server. This can be expressed as a curl command:

.. code-block:: bash
curl -X GET --header "Authorization: Bearer ACCESS_TOKEN" http://resource.example.org/some/path
Step 4. Access Token Validation
-------------------------------

The resource server has received an access token from a client application. Although the access token delivered by Agate is a JWT that contains in its payload all the basic information (subject identification, authorized scopes), it is the responsibility of the resource application to validate this token.

This can be achieved by requesting the REST end point:

.. code-block:: rest
GET https://agate.example.org/ws/ticket/ACCESS_TOKEN/_validate
Note that the resource application must identifies itself in this request. This can be expressed as a curl command:

.. code-block:: bash
curl -X GET --header "X-App-Auth: Basic `echo -n "APPLICATION_NAME:APPLICATION_KEY" | base64`" https://agate.example.org/ws/ticket/ACCESS_TOKEN/_validate
The expected response code is *200* (*OK*), without a response body.

Possible validation errors are:

* application could not be identified,
* access token signature verification has failed,
* access token issuer is not the current Agate instance,
* application is not part of the audience of the access token,
* access token has expired,
* user is not active any more.
Binary file added oauth2-api/images/agate-oauth.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
44 changes: 44 additions & 0 deletions oauth2-api/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
OAuth2 API
==========

Summary
-------

Agate exposes web services that implements the OAuth2 protocol. OAuth2 is an open authorization protocol which enables applications to access each others data. The authorization refers to the fact that these data are accessed on behalf of a resource owner.

For more details, the OAuth2 specifications are available at RFC6749. See also the OpenID Connect specifications built on top of OAuth2.

Roles
-----

The OAuth2 protocol defines several roles:

* the **resource owner** is the person or application that owns the data that is to be shared. In our case a user on Agate could be a resource owner. The resource they own is their data. The resource owner is depicted in the diagram as a person, which is probably the most common situation. The resource owner could also be an application.
* the **resource server** is the server hosting the resources. For instance, Opal or Mica are resource servers.
* the **client application** is the application requesting access to the resources stored on the resource server. These resources are owned by the resource owner. A client application could be an X-ray images analyser that extracts the image data from Opal.
* the **authorization server** is the server authorizing the client application to access the resources of the resource owner: this is the role of Agate. The authorization server and the resource server can be the same server, but it doesn't have to. When Agate is also the resource server, the resource that is accessed is the user profile.

.. image:: images/agate-oauth.png

Client ID, Client Secret and Redirect URI
-----------------------------------------

Before a client application can request access to resources on a resource server, the client application must first register with the authorization server associated with the resource server. In Agate this is done by adding the client as a new Application.

The registration is typically a one-time task. Once registered, the registration remains valid, unless the client application registration is revoked by the Agate's administrator.

At registration the client application is assigned a client ID and a client secret (password) by the authorization server. The client ID and secret is unique to the client application on that authorization server. In terms of Agate's domain, the client ID is the application's name and the client secret is the application's key.

During the registration the client needs to provide a redirect URI. This redirect URI is used when a resource owner grants authorization to the client application. When a resource owner has successfully authorized the client application via the authorization server, the resource owner is redirected back to the client application, to the redirect URI.

Scopes
------

The scopes are space-separated the application IDs, optionally qualified by a permission. As an example, if an application registered in Agate with ID **foo** declares the **read** permission (= the permission to access to the resource granted by foo is read-only), then the authorization scope will be **foo:read**. If no action is specified, Agate will assume that foo grants full access to the resource. The permissions are specific to the application and it is the responsibility of the resource server to handle them as announced.

Flows
-----

* :doc:`authorization-code-grant-flow`: when a client application wants access to the resources of a resource owner, hosted on a resource server, the client application must first obtain an authorization code grant from the authorization server (Agate).
* :doc:`resource-owner-password-credentials-grant-flow`: suitable for clients capable of obtaining the resource owner's credentials (username and password),
* :doc:`openid-connect-flow`: when client wants to get the user information from Agate (authorization and resource are the same).
5 changes: 5 additions & 0 deletions oauth2-api/openid-connect-flow.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Resource Owner Password Credentials Grant Flow
==============================================

Summary
-------
5 changes: 5 additions & 0 deletions oauth2-api/resource-owner-password-credentials-grant-flow.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
OpenID Connect Flow
===================

Summary
-------
6 changes: 6 additions & 0 deletions presentation/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
General Presentation
====================

Targeted at individual studies and study consortia, OBiBa software stack (Opal, Mica2 etc.) provides a software solution for epidemiological data management, analysis and publication. While Opal--the core data warehouse application--provides all the necessary tools to import, transform and describe data, Mica provides everything needed to build personalized web data portals and publish content of research activities of both studies and consortia. Based on the content defined in Mica, Drupal is the prefered platform to build your personalized web portal.

Agate is the OBiBa's central authentication server which intends to be easy to install and to use. Agate centralizes also some user related services such as profile management, and a notification system using emails.
2 changes: 2 additions & 0 deletions python-user-guide/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Python Client User Guide
========================
2 changes: 2 additions & 0 deletions web-user-guide/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Web Application User Guide
==========================

0 comments on commit 3a469e6

Please sign in to comment.