Skip to content

Auth details

This section describes how you can authenticate your client application or the users using your client application to be able to query the API. This information is useful if you plan on implementing this logic yourself. If however you can use the Obelisk client-library (only for client-side TS browser applications), this is done for you already.

Auth process

Requesting access

If you haven't requested access already, read that section first please. It will allow you to correctly issue an access request for your application.

Before any authorization (read: allowed use of the APIs) can happen, you must be authenticated. This can happen in a number of ways, depending on each specific case. The end result however, will always be some kind of access token representing your client and possibly the user using the client.

Your client will be registered as an application acting on behalf of users or on its own. In the former case you will receive a client_id in the latter case a client_id and a client_secret. These are called your client credentials and will be needed at some point in the auth process. You should have received these following the request access steps.

Implicit flow

Implicit flow lets a client immediately receive an access token to access the authorization APIs. It does so at the expense of sending the tokens in the redirect_uri. Because these clients typically can't keep a secret from the user agent or other processes on the client host, these clients themselves are not authenticated (just identified by a client_id). The client will also not receive a refresh_token, so after the access_token expires, authentication has to start all over again. This flow is typical for public applications that need to do a single (or a few short lived) task(s).

Hint

There are not a lot of cases where implicit is a good fit. You do not get a refresh token, so you cannot refresh. You have to redo the complete auth procedure again once the token expires. That is why this is typically suited for a one-off task.

Authorization code flow makes a client take an extra indirection step, making sure the token can't be easily intercepted by different attacks. After initial authentication, the client receives an access code (rather than an access token) that cannot immediately be used to access the authorization APIs.

This code must then be sent to the token endpoint (https://obelisk.ilabt.imec.be/auth/realms/idlab-iot/protocol/openid-connect/token) to receive the actual access_token. This must be done with an http POST request, not with a redirect. The response will contain an access_token and a refresh_token.

Hint

The client library uses this flow by default and calls it the 'standard' flow.

Step by step

This section explains the steps required to complete the auth process and end up with an RPT token that can be used to access the APIs.

1. Authentication

First we will authenticate ourselves to the identity server. There are two different ways to do this, depending on your desired application. Either the client is logging in on behalf of the user, or you have a client/service that authenticates on behalf of the client itself.

1.1 On behalf of user

The client wants to identify the user along with itself to the API. In this case your client is an application that is meant to be used by users as a tool that inherits their rights (to which they agree).

Hint

The obelisk-client library can do most of the heavy lifting for authentication/authorization for you, in case of a client-side JS/TS application. If you need to do this manually, follow the steps below.

a) Redirect to login

First we let your user log in. This can be done via a link to the following url:

https://obelisk.ilabt.imec.be/auth/realms/idlab-iot/protocol/openid-connect/auth?parameters...

parameter values description
client_id - This is the client_id from your client credentials received when registering the client applicaiton.
redirect_uri - This is the uri where the browser will be redirected to, once the login procedure is over.
state - Opaque value used to maintain state between the request and the callback. Typically, Cross-Site Request Forgery (CSRF, XSRF) mitigation is done by cryptographically binding the value of this parameter with a browser cookie.
nonce - A cryptographic string, that will be represented to the client in the requested token, to mitigate replay attacks (info here & here)
response_mode fragment query form_post How the token will be returned to the redirect_uri (fragment is highly recommended!)
response_type (see table below) Which OAuth 2.0 flow you are using.

Hint

In case of response_mode fragment the redirect uri will contain a hash fragment that contains a token.

response_type OAuth 2 flow description
code Authorization code flow Reponse will contain a code, that should be exchanged for a token at the token endpoint. (client should be able to keep code a secret from browser/other code, eg. a server backend that can do a back-channel request)
id_token Implicit flow Response will contain an id_token immediatly. (when clients can't keep a code secret, this is the go to flow)
id_token token Implicit flow Response will contain an id_token and acces token immediatly. (when clients can't keep a code secret, this is the go to flow)

Hint

We recommend using code for reasons explained in the Auth process section above.

Info

More optional paramaters can be added later. See also OIDC 1.0.

b) Retrieve code/token from hash

If you used the authorization code flow then read below for the next step, if not, read the tip at the end of this section.

At the redirect_uri location there should be a script that is able to extract the code from the hash (if you used response_mode fragment). After the login procedure is over, the redirect_uri will be called and in the hash fragment there will be a parameter code. Use this value to do a POST request with the following headers:

header value
Content-type application/x-www-form-urlencoded

and body (concatenated as form values param=value&param2=value2):

body parameter value
grant_type authorization_code
code code_value
redirect_uri https://my-example.app.com
client_id client_id

to: https://obelisk.ilabt.imec.be/auth/realms/idlab-iot/protocol/openid-connect/token

The received JSON response contains access_token, id_token and refresh_token (for the access_token).

Hint

If you chose to do a implicit flow, the access_token and possibly the id_token are in the redirect_uri hash and there is no need for an extra POST request. The id_token is for user customization in your client and of no importance for us anymore. (The format is JWT). The access_token is what we will use in step 2.

Info

Read more on the optional body parameter scope=offline_access on this page.

1.2 On behalf of client

First we authenticate your client. For this a valid client_id and client_secret pair are necessary. (they can be requested if you don't have them yet).

Our client credentials are encoded in an authString:

Base64Encode(client_id:client_secret)

Use this authString to do a POST request with the following headers:

header value description
Content-type application/x-www-form-urlencoded
Authorization Basic authString The string 'Basic ' with the value of authString appended to it.

and body (concatenated as form values param=value&param2=value2):

body parameter value
grant_type client_credentials

to: https://obelisk.ilabt.imec.be/auth/realms/idlab-iot/protocol/openid-connect/token

The received JSON response contains access_token and refresh_token (for the access_token).

Warning

Remember that this is only the access_token to authenticate yourself, this does not grant you access to the APIs just yet.

2 Getting the RPT token

The final step is to get the RPT, which is the actual access token needed to talk to the Obelisk APIs. For this we will send a HTTP POST request to this url:

https://obelisk.ilabt.imec.be/auth/realms/idlab-iot/protocol/openid-connect/token

The request will contains these headers

Header key Header value Description
Authorization Bearer access_token The access token we received in Step 1 prefixed with Bearer
Content-Type application/x-www-form-urlencoded Form format to send two important form parameters in the body

The request will contain these required form parameters:

Form param key Form param value
grant_type urn:ietf:params:oauth:grant-type:uma-ticket
audience policy-enforcer

You will receive a message that looks like this:

1
2
3
4
5
6
7
8
9
{
    "upgraded": false,
    "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiA...",
    "expires_in": 300,
    "refresh_expires_in": 1800,
    "refresh_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSl...",
    "token_type": "Bearer",
    "not-before-policy": 0
}

The access_token field is your RPT token. This is what you will use for every request to the API from now on. The refresh_token can be used to quickly refresh an expired access_token. The details are explained in Step 4

3 Call a resource

Now you can call a resource on the API by including this header:

Authorization: Bearer RPT

4 Refreshing the RPT

When you get a ERROR 401 response on a correct API resource call (like in Step 3), it probably means your RPT token expired. In Step 2 there was an expires_in field, which you can use to timely refresh your token. Refreshing your token is done by sending a HTTP POST request to

https://obelisk.ilabt.imec.be/auth/realms/idlab-iot/protocol/openid-connect/token

It should have the following header:

Content-Type: application/x-www-form-urlencoded

And contain the following form parameters:

Form param key Form param value
grant_type refresh_token
refresh_token refresh_token (from Step 2)
client_id client_id
client_secret client_secret (only if you needed a secret previously)

You will receive a message that looks like this:

1
2
3
4
5
6
7
8
9
{
    "upgraded": false,
    "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiA...",
    "expires_in": 300,
    "refresh_expires_in": 1800,
    "refresh_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSl...",
    "token_type": "Bearer",
    "not-before-policy": 0
}

The access_token field is your new RPT token. This is what you will use for every request to the API from now on. The refresh_token is also important, it has a new expiry date, so overwrite your previous refresh_token, else you will not be able to refresh continuously.