OAuth 2 Flows

Must read before starting

It's very important to choose the right type of clients and to understand the various OAuth flows.

A very good documentation is this one :

https://auth0.com/docs/authorization/which-oauth-2-0-flow-should-i-use

and another one

https://dzone.com/articles/the-right-flow-for-the-job-which-oauth-20-flow-sho

Here is a quick summary of which flow is designed to be used in a given scenario:

  • server-to-server (Client Credentials Flow):
    • standardFlowEnabled : false
    • consentRequired : false
    • redirectUri empty
    • serviceAccountEnabled : true 

so user can't login with this client, and the client must have the serviceAccount property set to true 

  • server-side app (Authorization Code Flow also called Standard Flow, it's the regular flow to establish a login page on your website accessible by your users):
    • standardFlowEnabled : true
    • consentRequired : true
    • redirectUri : not empty, not localhost, https only
  • SPA: Single-Page-Application, basically app without backend, public client with Authorization Code Flow and PKCE enforcement by us
    • publicClient : true
    • standardFlowEnabled : true
    • consentRequired : true
    • redirectUri : not empty, not localhost, https only
  • mobile: Authorization Code Flow
    • Same as SPA public or confidential depending if the mobile App use a backend

Note : We are not allowing Implicit Flow, we are not allowing Standard flow without consentRequired and redirectUri either, for security reason. FYI, your public client for SPA usage will be enforced automatically by us with the PKCE feature.

Abstract

This wiki page is for service providers whose apps need to authenticate with the EBRAINS Single Sign-On. EBRAINS users need to be in the "service providers" Group to access to manage an OIDC client.

A previous version of this documentation explained how to create an OIDC Client using the native Keycloak API. It was a bit complex for users. They had to fetch a specific developer access token, then create the OIDC client, and safely store the registrationAccessToken and safely store a new token after every one of their updates. There were limitations on scope editions. There was no notion of OIDC client ownership making it difficult to manage who could edit settings for the OIDC client. And there was no option to grant access to the OIDC client to a limited set of EBRAINS users.

All these issues have been solved with the new OIDC Client API provided in the Collaboratory API. OIDC client owners can now use their usual collab access token (e.g. from a notebook in the Collaboratory Lab) to create and manage their OIDC Client. They no longer have to safely store a registrationAccessToken. They can provide a list of maintainers that are allowed to update the OIDC client. And they can also choose which end users can be granted access via their OIDC client.

This documentation describes the available endpoints and the JSON format excepted by the API. A more concrete example is also provided in a Lab notebook.

UI to create and manage your clients

The newest addition to the OIDC client creation process on the Collaboratory is a UI to help you manage, create and update your clients.  You can find this by visiting https://wiki.ebrains.eu/bin/view/OIDC/.

To create a new OIDC client click on the "Create new client" button as shown in the following image:

image-20230209111255-1.png

The UI will explain all of the options you can choose from. To update any client alraedy existing, click on the client in the list. For example, in the above example, if I wanted to update the client "pauls test client" I would click on that entry in the list.

Lab notebook to create and manage your client

A live example of OIDC Client creation is available here to be run in the Collaboratory Lab.

The next steps in this documentation reproduce the content of the notebook. We strongly recommend that service providers use this notebook to create their OIDC client. It's the easiest way to avoid any mistake.

Create a localhost client for developement on our integration enviroment

You can't create client with redirectUri localhost in production. If you want to create a client for development purpose, please use our integration environement

Registration on integration environement : https://iam-int.ebrains.eu/register

Wiki group to access lab : https://wiki-int.ebrains.eu/bin/view/Identity/#/groups/app-collaboratory-lab--access
Wiki group to access OIDC API : https://wiki-int.ebrains.eu/bin/view/Identity/#/groups/app-collaboratory-iam--service-providers

For now, contact our support to be granted on lab-int and get developer accreditation

Notebook to create client : https://lab-int.ebrains.eu/hub/user-redirect/lab/tree/shared/%EF%BB%BFThe%20Collaboratory/Managing%20an%20OpenID%20Connect%20client%20-%20V2.ipynb

Endpoints

POST :     https://wiki.ebrains.eu/rest/v1/oidc/clients
PUT   :     https://wiki.ebrains.eu/rest/v1/oidc/clients/{clientId}
GET   :     https://wiki.ebrains.eu/rest/v1/oidc/clients/{clientId}

The POST/PUT API endpoints use the same JSON format to describe the OIDC client.

The GET API endpoint returns a valid JSON format, which can be edited and used to update an OIDC client. It's the recommended way of updating an OIDC client: first fetch your OIDC client's info, then edit the JSON. This reduces the risk of forgetting data in the JSON of POST/PUT call which would delete the missing data from the OIDC client configuration.

JSON Format

Find below an example JSON format and an explanation of its fields.


{
"client": {
   "clientId": "tutorialOidcApi",
   "name": "Tutorial OIDC API",
   "description": "A sample client demo for the OIDC API documentation",
   "rootUrl": "https://example.org",
   "baseUrl": "https://example.org",
   "redirectUris": [
       "https://example.org/login/*"
    ],
   "bearerOnly": false,
   "consentRequired": true,
   "standardFlowEnabled": true,
   "implicitFlowEnabled": false,
   "directAccessGrantsEnabled": false,
   "attributes": {
       "contacts": "first.contact@example.com; second.contact@example.com"
    },
   "defaultClientScopes": ["openid", "email"],
   "optionalClientScopes": ["profile","team","group"]
},
"maintainers": ["messines","bougault"],
"featureAuthenticate" : false,
"accessDeniedToGuests" : false
}

client

The JSON provided to the OIDC app API must contain a "client" object. It's the same JSON as in the previous versions of the documentation using the Keycloak native API. You can use all the attributes available in the ClientRepresentation object natively used by Keycloak and described here.

maintainers

This list field is optional. The OIDC client owner can provide a list of maintainers. The values in the list must be valid usernames of EBRAINS users. Even if this field is not provided, the OIDC client can always also be maintained by its owner. An OIDC client is now automatically configured with an owner property which stores the username of the EBRAINS user creating the OIDC client.

featureAuthenticate

This boolean field is optional. If it is not provided, it defaults to false. If set to true, EBRAINS users will not be able to gain access to your OIDC client unless they are in a Collaboratory Group or Collaboratory Unit which has the "feature:authenticate" role for your OIDC client.

Service providers wanting to use this feature should set it to true in the JSON request to create/update their OIDC client. They should then use the API endpoints below to grant (PUT) or revoke (DELETE) access.
 

PUT/DELETE: https://wiki.ebrains.eu/rest/v1/oidc/clients/{clientId}/groups/{groupsName}

PUT/DELETE: https://wiki.ebrains.eu/rest/v1/oidc/clients/{clientId}/units/{unitPath}

Example to grant access to HBP members

PUT: https://wiki.ebrains.eu/rest/v1/oidc/clients/tutorialOidcApi/units/all:projects:hbp

Example to grant access to TVB Workshop attendees

PUT: https://wiki.ebrains.eu/rest/v1/oidc/clients/tutorialOidcApi/groups/TVB-Workshops

EBRAINS users can visit https://wiki.ebrains.eu/bin/view/Identity and from there browse Units to find the relevant unitPath in the Unit tree.

A more complete documentation on How to grant access is available in the notebook. If you don't feel confident in managing specifically access to your client, the easiest is maybe to let your authentication open to all EBRAINS users as it is currently the case by letting featureAuthenticate property to false.

Warning: if you switch featureAuthenticate from true to false, all the Group/Unit specific accesses that were configured will be lost and will have to be granted again if you switch from false to true again.

accessDeniedToGuests

This boolean field is optional. If it is not provided, it defaults to true, meaning that Guest users won't be able to access your OIDC client.

Service providers who want to provide access to EBRAINS guest accounts can set this field to false. Use of EBRAINS resources by EBRAINS guests accounts is the service provider's responsibility. Guest users might be insufficiently identified, might not be legally liable, might not be part of the target audience of the EBRAINS platform. See Guest accounts for more information before granting such an access and contact EBRAINS Support in case of doubt.

How to GET and UPDATE your client

Service providers who want to see your OIDC client settings can GET the API endpoint as shown below, with their access token, e.g. the token from the Collaboratory Lab.
 

GET: https://wiki.ebrains.eu/rest/v1/oidc/clients/{clientId}/

e.g. GET: https://wiki.ebrains.eu/rest/v1/oidc/clients/tutorialOidcApi/

The response will look like:

{
   "client": {
       "id": "tutorialOidcApi",
       "clientId": "tutorialOidcApi",
       "name": "Tutorial OIDC API",
       "description": "A sample client demo for the OIDC API documentation",
       "rootUrl": "https://example.org",
       "adminUrl": null,
       "baseUrl": "https://example.org",
       "surrogateAuthRequired": false,
       "enabled": true,
       "alwaysDisplayInConsole": false,
       "clientAuthenticatorType": "client-secret",
       "secret": "IooQSAmrbPUqYgHdkklBMPsIBKlupUi",
       "registrationAccessToken": null,
       "redirectUris": [
           "https://example.org/login/*"
        ],
       "webOrigins": [
           "https://example.org"
        ],
       "bearerOnly": false,
       "consentRequired": true,
       "standardFlowEnabled": true,
       "implicitFlowEnabled": false,
       "directAccessGrantsEnabled": false,
       "serviceAccountsEnabled": false,
       "publicClient": false,
       "frontchannelLogout": false,
       "protocol": "openid-connect",
       "attributes": {
           "contacts": "first.contact@example.com; second.contact@example.com"
        },
       "authenticationFlowBindingOverrides": {},
       "fullScopeAllowed": false,
       "nodeReRegistrationTimeout": -1,
       "registeredNodes": null,
       "defaultClientScopes": [
           "openid",
           "email"
        ],
       "optionalClientScopes": [
           "profile",
           "team",
           "group"
        ],
       "access": null,
       "origin": null
    },
   "owner": "messines",
   "maintainers": [
       "messines",
       "bougault"
    ],
   "accessDeniedToGuests": false,
   "featureAuthenticate": false,
   "grantedAccess": {
       "users": [],
       "units": [],
       "groups": []
    },
   "featureAuthenticateIntValue": 0,
   "guestPropertyIntValue": 0
}

Then to update the OIDC client settings, the easiest and recommended way is to copy the JSON received from the GET request, to edit it, and run a PUT request on the OIDC client endpoint with the JSON added as body of the request.

e.g. PUT: https://wiki.ebrains.eu/rest/v1/oidc/clients/tutorialOidcApi/

The following attributes should be removed before resending the JSON to the PUT endpoint, or they will simply be ignored:

  • grantedAccess
  • featureAuthenticateIntValue
  • guestPropertyIntValue
  • owner

To change the owner of an OIDC client, the current owner should contact EBRAINS support.

Using your new OIDC client as a service account

To use your new OIDC client as a service account, please read our tutorial on how to do this.

Tags:
    
EBRAINS logo