Authenticating with your OIDC client and fetch collab user info

Version 13.1 by mmorgan on 2020/07/16 03:29

Abstract

In order to create an OIDC client, see 1. Registering an OIDC client. After creating the OIDC client, you have a corresponding access token and secret.

For the example below, we consider the case of someone wanting to provide access to https://www.getpostman.com as an app for Collaboratory users to access from their collabs. You should replace that URL by the one of your own app.

The redirect_uri is set with the URL of your application to which your users will be redirected after having been authenticated by their EBRAINS account. For example when you login to this wiki, the redirect URI is https://wiki.ebrains.eu/*

Screenshot 2020-07-15 at 17.47.12.png

The whole authentication flow presented here is based on the official OAuth2 RFC described in the section 4.1.

https://tools.ietf.org/html/rfc6749#section-4.1

Screenshot 2020-07-15 at 18.32.14.png

Authentication flow

Authorization Code Request

The first step of the authentication protocol is to fetch an authorization code for your client and your user. This is done by directing your users to the URL of the EBRAINS login page (IAM) where they can enter their username and password.

Request

The authorization code is fetched by an HTTP request:

/GET: https://iam.ebrains.eu/auth/realms/hbp/protocol/openid-connect/auth

with the following parameters:

  • response_type=code
  • login=true
  • client_id=community-apps-tutorial
  • redirect_uri=https://www.getpostman.com/oauth2/callback
  • scope=openid+group+team

with the italics indicating the fields you customize for your own app. The URL will look like:

https://iam.ebrains.eu/auth/realms/hbp/protocol/openid-connect/auth?response_type=code&login=true&client_id=community-apps-tutorial&redirect_uri=https://www.getpostman.com/oauth2/callback&scope=openid+group+team

The scope parameter can include a combination of several values. Each user will be asked to consent to sharing that scope with your app upon first access.

  • openid: This scope is required because we use the OIDC protocol. It will give your app access to the user's basic information such as username, email and full name.
  • group (optional)If you request this scope, the future access token generated will authorize your app to identify which units and groups the user belongs to.
  • team (optional)This scope is like the group scope lets your app identify the permissions of the user, but by identifying what collabs the user has access to and with what roles.

The group and team scopes are a simple way for your app to grant permissions to its services and resources when you want to grant access to a very few units, groups, or collab teams. For more complex permission management, contact support.

Response

Once the user has logged in, your app gets an HTTP 301 redirection followed by an HTTP 200 success response with an authorization code inside. A typical response might look like:

https://www.getpostman.com/oauth2/callback?session_state=a0ff8a68-2654-43ef-977a-6c15ce343546&code=f3f04f93-hbp-482d-ac3d-demo.turtorial.7122c1d9-3f7e-4d80-9c4f-dcd244bc2ec7

The authorization code is the part in bold in the response above.

Access Token Request

Now that your app has the authorization code for a user, it can fetch the user access token

Request

/POST: https:/iam.ebrains.eu/auth/realms/hbp/protocol/openid-connect/token

with the following parameters:

  • grant_type: authorization_code
  • code: f3f04f93-hbp-482d-ac3d-demo.turtorial.7122c1d9-3f7e-4d80-9c4f-dcd244bc2ec7
  • redirect_uri: https://www.getpostman.com/oauth2/callback
  • client_id: community-apps-tutorial
  • client_secret: your client secret obtained during client creation

The image below shows a sample POST request generated from the Postman tool. [The fact that this page is based on getpostman.com as an example is pure coincidence.]

Screenshot 2020-07-15 at 18.20.34.png

Response

200 OK

{
    "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAi...pP5vaNwvvsaNGEA",
    "expires_in": 604773,
    "refresh_expires_in": 604773,
    "refresh_token": "eyJh...vC5eIR1rNhRJ4d8",
    "token_type": "bearer",
    "id_token": "eyJ...YOwdQ",
    "not-before-policy": 0,
    "session_state": "76e553bf-ba2e-45b6-8c6c-c867772b40ec",
    "scope": "openid"
}

Your app gets a response containing the access token and other information.

Access user info

Now that your app has the access token of a user, it can fetch the user's info.

Request

/GET: https:/iam.ebrains.eu/auth/realms/hbp/protocol/openid-connect/userinfo

with the following parameters:

  • Authorization: the access token preceded by the string "Bearer "

The image below shows a sample GET request generated from the Postman tool. [The fact that this page is based on getpostman.com as an example is pure coincidence.]

Screenshot 2020-07-15 at 18.28.28.png

Response

As response your app receives a JSON with all the information on the logged user

{
    "sub": "fa2db206-3...0ebaba98e1",
    "unit": [
        "/collab-devs",
        "/collab-team",
        "/all/institutions/switzerland/epfl",
        "/all/projects/hbp/consortium/SGA2/SP05",
        "/all/projects/hbp/consortium/SGA3/WP6/T6_11"
    ],
    "roles": {
        "jupyterhub": [
            "feature:authenticate"
        ],
        "xwiki": [
            "feature:authenticate"
        ],
        "team": [
            "collab-collaboratory-community-apps-editor"
        ],
        "group": [
            "group-collaboratory-developers",
            "unit-all-projects-hbp-consortium-sga2-sp05-administrator"
        ]
    },
    "mitreid-sub": "30...62"
}

The group field above lists Collaboratory Groups in the form "group-groupname" and Collaboratory Units in the form "unit-unitname" with the unitname using dashes instead of the colons you see in the Collaboratory UI.

The team field above lists Collaboratory Teams in the form "collab-collabname-role" where role is one of admin, editor, or viewer according to the user's role in collab collabname.

jupyterhub and xwiki are OIDC clients.

The unit field above lists [useless noise?].