Guide d’utilisation des Web Services REST

Chaque utilisateur de CLIMATIK peut utiliser les Web Services de l’application pour récupérer les données climatiques dans son application sans passer par l’interface web. Ce document liste les web services REST de l’application CLIMATIK.

Versions du document

Date Auteur Objet
20/03/2020 Olivier Création
06/04/2020 Olivier Précision sur les séquences OAuth2
20/04/2020 Olivier Ajout de l’exemple en HTML + JavaScript
13/05/2020 Olivier API 1.0.1 Ajout de la séquence device_code
24/06/2020 Olivier API 1.0.2 Ajout des points d’accès /rs/files et /rs/files/{id}
21/09/2020 Olivier Ajout du paragraphe Utilisations de l’API
15/10/2020 Olivier API 1.0.3 Ajout des disponibilités des données dans /rs/stations
02/11/2020 Jérémie API 1.0.4 Ajout du réseau dans le GeoJSON
19/05/2021 Olivier Ajout d’exemples pour générer code_challenge à partir de code_verifier
21/07/2021 Olivier Précision sur le type de jeton à utiliser dans les entêtes HTTP
17/11/2021 Jérémie Ajout de l’exemple en R
25/11/2021 Olivier Suppression des références à SOAP
09/09/2022 Olivier Ajout de l’exemple en Bash
18/09/2023 Jérémie Suppression de l’exemple en R

Documents de référence

L’ensemble des web services REST est auto-documenté dans le format OpenAPI3 à https://agroclim.inrae.fr/climatik/openapi/openapi.json. Vous pouvez visualiser la documentation dans Swagger UI. Vous pouvez aussi consulter le fichier WADL (Web Application Description Language) à https://agroclim.inrae.fr/climatik/rs/application.wadl.

Authentification

L’authentification de l’utilisateur utilise le protocole OAuth2.

OAuth2 est un protocole qui permet à des applications externes de demander l’autorisation d’accéder à des informations privées d’un utilisateur avec un compte applicatif et de faire des actions en son nom. L’utilisateur n’a pas besoin de fournir son mot de passe applicatif à l’application externe et reste maître des autorisations qu’il a fournies.

La première chose à faire est d’enregistrer l’application (site ou programme) dans CLIMATIK. Vous devrez renseigner obligatoirement un nom, une description et les portées utilisées. Pour enregistrer un site, il faudra renseigner aussi l’adresse du site web, un logo et le domaine, ce seront des informations présentées à l’utilisateur quand il sera renvoyé de votre site web sur CLIMATIK. Le domaine devra correspondre à l’adresse de retour redirect_url. Un identifiant et un secret seront généré pour votre application. Le secret doit, comme son nom l’indique, rester secret. Un identifiant et un secret serviront lors des échanges OAuth dans la séquence avec identifiants. L’identifiant sans le secret servira dans la séquence avec code d’autorisation.

Les portées (scope) possibles sont : data:read.

Dans un premier temps, l’enregistrement du client est à demander à support-climatik@inrae.fr, veuillez fournir les informations nécessaires :

  • nom de l’application
  • description
  • logo
  • URL du site web
  • hôte de l’URL de redirection (pour la séquence PKCE)
  • les portées utilisées (data:read uniquement pour l’instant)

OAuth2 fonctionne avec un principe de jetons. La séquence d’obtention du jeton dépend du type d’application utilisant l’API. Trois séquences sont disponibles suivant l’utilisation :

  • identifiants client (Client credentials) pour les programmes sans interaction avec l’utilisateur,
  • code d’autorisation pour appareils (Device code) pour les programmes qui ne peuvent intéragir avec un utilisateur dans un navigateur,
  • code d’autorisation avec PKCE (Authorization Code with Proof Key with Code Exchange) pour les applications qui interagissent avec un utilisateur dans un navigateur.

Deux types de jetons sont utilisés :

  • access_token : un jeton avec une validité de 6 heures, à utiliser dans les web services CLIMATIK
  • refresh_token : un jeton avec une validité d’un an, à utiliser dans les web services OAuth2 pour l’obtention d’un nouveau jeton access_token

Séquence identifiants client

Avec les applications machine-to-machine (M2M), telles que les scripts, démons ou services tournant en tâche de fond, le système authentifie et autorise l’application cliente et, à travers elle, l’utilisateur. De telles applications utilisent donc la séquence avec les identifiants clients (Client Credentials Flow, définie par OAuth 2.0 RFC 6749, section 4.4), pour laquelle elles passent leurs identifant et code secret pour les authentifier et obtenir un jeton.

Voici la séquence :

  1. Votre application s’authentifie sur CLIMATIK avec client_id et client_secret sur l’URL /rs/oauth/token
    {
      'client_id': 1234567,
      'client_secret': 'ABCDEF1234',
      'grant_type': 'client_credentials'
    }
  1. CLIMATIK valide ces valeurs et renvoie un jeton d’accès access_token.
  2. Votre application peut utiliser ce jeton pour appeler l’API de CLIMATIK en son nom.
  3. L’API de CLIMATIK répond avec les données demandées.

Séquence code d’autorisation pour appareils

Avec les appareils qui se connectent à Internet mais où l’interaction avec l’utilisateur est limitée, plutôt que d’authentifier l’utilisateur directement, l’appareil demande à l’utilisateur d’aller sur un lien sur son ordinateur ou un ordiphone pour autoriser l’appareil. Cela évite à l’utilisateur la complexité d’interagir avec ces appareils limités. Pour réaliser cela, les applications pour appareil utilisent la séquence de code d’autorisation pour appareils (Device Authorization Flow, définie par OAuth 2.0 RFC 8628), dans laquelle ils utilisent leur identifiant client pour commencer le processus d’authorisation et obtenir un jeton.

L’obtention d’un jeton d’autorisation se fait en plusieurs étapes :

sequenceDiagram participant Utilisateur participant VotreApp participant CLIMATIK participant CAS Utilisateur->>VotreApp: lance votre application VotreApp->>CLIMATIK: demande l'autorisation à /rs/oauth/device/code CLIMATIK->>VotreApp: retourne device_code, user_code et les URL de vérification VotreApp->>Utilisateur: affiche user_code avec une URL de vérification loop toutes les 5s VotreApp->>CLIMATIK: interroge /rs/oauth/token pour obtenir access_token end Utilisateur->>CLIMATIK: ouvre l'URL de vérification opt Si l'utilisateur n’est pas identifié dans CLIMATIK CLIMATIK->>Utilisateur: renvoie sur le CAS Utilisateur->>CAS: s'identifie sur le CAS CAS->>Utilisateur: renvoie sur CLIMATIK Utilisateur->>CLIMATIK: . CLIMATIK->>CAS: authentifie l'utilisateur end CLIMATIK->>Utilisateur: demande confirmation de l'accès et de user_code Utilisateur->>CLIMATIK: confirme l'accès CLIMATIK->>VotreApp: /rs/oauth/token retourne le jeton access_token VotreApp->>CLIMATIK: utilise access_token pour les appels REST
  1. L’utilisateur lance votre application.
  2. Votre application demande l’autorisation à CLIMATIK en utilisant client_id à l’URL /rs/oauth/device/code.
  3. CLIMATIK retourne device_code, user_code, verification_uri, verification_uri_complete, expires_in (délai en secondes pour l’utilisation de device_code et user_code) et interval (la fréquence maximale d’interrogation en secondes).
  4. Votre application demande à l’utilisateur d’activer l’accès en utilisant un navigateur (ordinateur, ordiphone, tablette…). L’application peut le réaliser en :
    • demandant à l’utilisateur de visiter verification_uri et d’entrer user_code après avoir affiché ces valeurs à l'écran,
    • demandant à l’utilisateur d’utiliser un QR Code ou une URL raccourcie pointant vers verification_uri_complete,
    • ouvrant directement un navigateur vers verification_uri_complete.
  5. Votre application commence à interroger CLIMATIK pour obtenir access_token à l’URL /rs/oauth/token à la fréquence définie par interval (en secondes), à compter de la réception de la dernière réponse du web service. Votre application continue l’interrogation jusqu'à ce que l’utilisateur termine son action dans le navigateur ou jusqu'à l’expiration définie par expires_in (en secondes).
  6. Lorsque l’utilisateur a terminé son activation dans le navigateur, CLIMATIK retourne au travers de /rs/oauth/token access_token et refresh_token. Votre application peut oublier device_code qui a expiré.
  7. Votre application peut utiliser access_token dans les appels aux API dans les entêtes HTTP : Authorization: Bearer $ACCESS_TOKEN.

Les URL à appeler sur CLIMATIK sont :

  • POST /rs/oauth/device/code avec pour entête HTTP content-type: application/x-www-form-urlencoded et pour corps client_id=XXXX&scope=data:read
  • POST /rs/oauth/token avec pour entête HTTP content-type: application/x-www-form-urlencoded et pour corps client_id=XXXX&device_code=XXXX&grant_type=device_code La réponse sera du type
{
    "access_token":"eyJz93a...k4laUWw",
    "refresh_token":"GebRxBN...edjnXbL",
    "token_type":"Bearer",
    "expires_at":123456789,
    "expires_in":86400
}

L’exemple en Python 3 peut être appelé ainsi pour cette séquence :

python3-oauth2.py -i CLIENT_ID -f device_code

Séquence code d’autorisation avec PKCE

Avec les applications web, l’intéraction avec l’utilisateur est possible. L’application web renvoie l’utilisateur sur CLIMATIK pour l’authentification par le processus habituel. Quand une application externe souhaite accéder aux données confidentielles de l’utilisateur, elle va demander à l’utilisateur un jeton d’autorisation qui sera délivré par l’application, puis il pourra utiliser ce jeton pour accéder aux informations. Pour réaliser cela, ces applications utilisent la séquence de code d’autorisation avec PKCE (Proof Key for Code Exchange, définie par OAuth 2.0 RFC 7636).

L’obtention d’un jeton d’autorisation se fait en plusieurs étapes :

sequenceDiagram participant Utilisateur participant VotreApp participant CLIMATIK participant CAS Utilisateur->>VotreApp: clique sur authoriser l’accès à CLIMATIK VotreApp->>VotreApp: génère code_verifier et code_challenge VotreApp->>CLIMATIK: demande l’autorisation par code avec code_challenge à /rs/oauth/autorize opt Si l'utilisateur n’est pas identifié dans CLIMATIK CLIMATIK->>Utilisateur: renvoie sur le CAS Utilisateur->>CAS: s'identifie sur le CAS CAS->>Utilisateur: renvoie sur CLIMATIK Utilisateur->>CLIMATIK: . CLIMATIK->>CAS: authentifie l'utilisateur end CLIMATIK->>Utilisateur: demande l’autorisation d'accès Utilisateur->>CLIMATIK: accepte la demande CLIMATIK->>VotreApp: retourne l’utilisateur avec le code d’authorisation à redirect_url VotreApp->>CLIMATIK: envoie access_code + code_verifier à /rs/oauth/token CLIMATIK->>CLIMATIK: valide CLIMATIK->>VotreApp: retourne le jeton access_token VotreApp->>CLIMATIK: utilise access_token pour les appels REST
  1. L’utilisateur clique sur un lien dans votre application.
  2. Votre application génère une chaîne de caractères aléatoire code_verifier et à partir d’elle génère un code_challenge.
  3. Votre application envoie votre utilisateur sur l’application CLIMATIK à l’URL /rs/oauth/authorize.
  4. CLIMATIK authentifie l’utilisateur avec le CAS INRAE.
  5. CLIMATIK affiche une page à l’utilisateur pour qu’il accepte ou refuse de donner l’autorisation à votre application.
  6. Si l’utilisateur accepte l’autorisation, CLIMATIK mémorise code_challenge et renvoie l’utilisateur sur le site d’origine avec un code temporaire code.
  7. Votre application renvoie ce code temporaire avec la valeur code_verifier à CLIMATIK à l’URL /rs/oauth/token.
  8. CLIMATIK vérifie code, code_verifier et code_challenge et renvoie un jeton d’accès (access_token) et un jeton de rafraichissement (refresh_token).
  9. Lors de l’appel des API sur les données, le bearer_token doit être envoyé dans les entêtes HTTP : Authorization: Bearer $ACCESS_TOKEN.

La chaîne de caractères code_challenge est obtenue en appliquant la méthode de Hash code_challenge_method (SHA256 uniquement) sur code_verifier et envoyée à /rs/oauth/authorize. La chaîne de caractères code_verifier est une chaîne aléatoire qui est envoyée à /rs/oauth/token. Retrouvez ci-dessous des exemples de génération de ces codes.

Les URL à appeler sur CLIMATIK sont :

  • GET /rs/oauth/authorize?client_id=XXXX?code_challenge=XXXX&code_challenge_method=s256&grant_type=code&redirect_uri=XXXX&response_type=code&scope=XXXX+XXXX&state=XXXX
  • POST /rs/oauth/token avec pour entête HTTP content-type: application/x-www-form-urlencoded et pour corps : client_id=XXXX&code=XXXX&code_verifier=XXXX&grant_type=code&redirect_uri=XXXX. La réponse sera du type
{
    "access_token":"eyJz93a...k4laUWw",
    "refresh_token":"GebRxBN...edjnXbL",
    "token_type":"Bearer",
    "expires_at":123456789,
    "expires_in":86400
}

Voici quelques exemples pour générer code_challenge à partir de code_verifier :

  • en Java :
import java.security.MessageDigest;
import java.util.Base64;
..
final byte[] bytes = codeVerifier.getBytes("ASCII");
final MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(bytes, 0, bytes.length);
final byte[] digest = md.digest();
return Base64.getUrlEncoder().withoutPadding().encodeToString(digest);
  • en JavaScript :
/**
 * @return promise ArrayBuffer
 */
function sha256(message) {
        const encoder = new TextEncoder();
        const data = encoder.encode(message);
        return window.crypto.subtle.digest('SHA-256', data);
}

/**
 * Convert the ArrayBuffer to string using Uint8 array.
 */
function base64urlencode(a) {
        return btoa(String.fromCharCode.apply(null, new Uint8Array(a)))
                .replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
}

/**
 * BASE64URL-ENCODE(SHA256(ASCII(code_verifier))).
 * @param code code verifier
 */
async function generate_code_challenge(code) {
        const code_sha256 = await sha256(code);
        return base64urlencode(code_sha256);
}
  • en Python :
import base64, hashlib
code_challenge = base64.urlsafe_b64encode(hashlib.sha256(code_verifier.encode('utf-8')).digest()).decode('utf-8').replace('=', '')

Il y a aussi quelques exemples de génération de ces codes sur le site Auth0.com.

Récupérer un nouveau jeton d’accès

Un jeton d’accès a une durée de validité limitée, la réponse de /rs/oauth/token renvoie expires_in, expires_at

ou pour rafraichir le jeton d’accès, en utilisant l’entête HTTP Authentication: Bearer $ACCESS_TOKEN

{
	"client_id":"XXXX",
	"code":"$REFRESH_TOKEN",
	"grant_type":"refresh_token"
}

La réponse sera la même que lors du premier appel à /rs/oauth/token.

Révocation d’un accès

Si vous voulez permettre à l’utilisateur de révoquer l’accès de votre application à CLIMATIK, vous pouvez appeler oauth/deauthorize en POST avec l’entête HTTP Authentication: Bearer $ACCESS_TOKEN. Tous les jetons donnés seront invalidés.

Description technique des services

CLIMATIK offre 6 points d’accès pour les données et métadonnées :

  • /rs/data
  • /rs/files
  • /rs/files/{id}
  • /rs/series et sa déclinaison en GeoJSON /rs/series/geojson
  • /rs/stations et sa déclinaison en GeoJSON /rs/stations/geojson
  • /rs/variables

Les appels aux données /rs/data et sur les fichier /rs/files et /rs/files/{id} nécessitent l’utilisation de l’entête HTTP Authentication: Bearer $ACCESS_TOKEN. Cela est rappelé par le symbole de cadenas 🔓.

Les réponses au format GeoJSON des points /rs/series/geojson et /rs/stations/geojson peuvent être directement visualisables par des bibliothèques JavaScript de cartographie web (OpenLayers, Leaflet) ou autres outils en ligne (https://geojson.io/, https://geojson.tools/).

Les autres réponses sont de la forme suivante :

{
    "message": "ok",
    "status": 200,
    "start": 1234,
    "end": 1243,
    "count": 10,
    "data": {...},
}

Utilisations de l’API REST

La plateforme VSoil utilise l’API REST à la place de l’API SOAP depuis la version 1.20200907.

Exemples de consommation

En Bash

Vous pouvez récupérer un exemple fonctionnel bash-oauth2.sh utilisant la séquence client_credentials. Vous devez définir les variables d’environnement CLIMATIK_CLIENT_ID et CLIMATIK_CLIENT_SECRET, par exemple en saisissant dans le terminal :

export CLIMATIK_CLIENT_ID=1111
export CLIMATIK_CLIENT_SECRET=XXXXXXXXXXXX

En JavaScript

Vous pouvez récupérer un exemple fonctionnel pkce-oauth2.html utilisant la séquence code d’autorisation avec PKCE.

En Python3

Vous pouvez récupérer un exemple fonctionnel python3-oauth2.py utilisant la séquence client_credentials ou device_code.

Document créé le : 2020-03-20
Dernière modification : 2024-03-29