REST API: S’authentifier

Généralement, la première étape afin de pouvoir utiliser une API est l’authentification. Cet article présente quelques mécanismes d’authentification couramment utilisés et accessibles en lignes, afin que vous puissiez les utiliser par vous même 🙂

Avant cela, commençons par un bref rappel sur ce qu’est une API.

1 – Généralités

Tous les éditeurs proposent désormais des APIs (REST, SOAP, NETCONF, RESTCONF, etc.) pour faciliter l’exploitation et la supervision de leurs produits. L’utilisation d’API permet de faciliter l’automatisation de tâches grâce à des méthodes standards et des codes de retours… Fini l’envoi de commandes en CLI et l’utilisation de regex pour parser les retours de l’équipements, en espérant qu’à la prochaine mise à jour des équipements la syntaxe reste la même…

On va s’intéresser ici aux APIs de type REST qui est la plus fréquemment rencontrée (Cisco DNA Center, Cisco ISE, Mist, Aruba Central, Meraki, Gmail, GitHub etc.). Les API REST sont basées sur HTTP: on interroge un serveur à une URL prédéfinie, via une méthode. Le serveur répond à cette requête en réalisant l’action demandée et en fournissant en retour le statut, sous forme d’un code numérique, de l’action.

Les éditeurs précisent dans la documentation de leurs APIs, les URLs à interroger pour chaque action possible sur l’application. Par exemple, voici le format d’une URL permettant de lister les bornes Wi-Fi présentes sur une solution Cisco DNA Center:

Exemple d’une URL permettant de réaliser une requête au format REST API

La requête REST est envoyée au serveur à cet URL, en utilisant une des méthodes suivantes:

  • POST: pour créer,
  • GET: pour lire,
  • PUT: pour modifier,
  • DELETE: pour supprimer

Le serveur, en retour, renvoi un code indiquant le statut du résultat de la requête. Il s’agit des codes HTTP classiques (2xx: succès, 4xx: erreur coté client, etc.). La réponse du serveur peut-être accompagnée de données, généralement au format JSON ou XML.

2 – Quelques méthodes d’authentification

Nous allons voir ici:

  • API sans authentification,
  • API avec authentification de type Basic,
  • API avec authentification de type API Key

API sans authentification

Il s’agit généralement de services en lecture seule, permettant de consulter une base. On va prendre ici l’exemple du site https://macvendors.com/api qui fournit une API renvoyant le fabricant correspondant à une adresse MAC en se basant sur son OUI.

En consultant la documentation de l’API, on retrouve les informations suivantes:

  • Le FQDN du serveur est api.macvendors.com et il est joignable via HTTPS,
  • le chemin vers l’API pour collecter le fabricant associé à l’adresse MAC est /,
  • la méthode à utiliser est la méthode GET

Voici un script Python permettant d’utiliser cet API. La requête est faite dans la fonction oui_lookup qui prend en paramètre l’adresse MAC à identifier:

from requests import get
from argparse import ArgumentParser

def oui_lookup(mac_address):
    URL = 'https://api.macvendors.com/'     
    result = get(URL + mac_address)
    return(result.text)

if __name__ == '__main__':
    parser: ArgumentParser = ArgumentParser(description='Perform an OUI lookup for the MAC address provided')
    parser.add_argument('-m', '--mac', help='MAC address to lookup in OUI database', type=str, required=True)    
    args = parser.parse_args()

    constructor = oui_lookup(args.mac)
    print(f"Constructor for MAC address {args.mac} is {constructor}")

API avec authentification « Basic »

Le premier exemple d’authentification que nous verrons ici, est l’authentification « Basic ». C’est une méthode d’authentification HTTP définie dans la RFC 2617. Elle n’est pas sécurisée puisque les identifiants sont envoyés au serveur non chiffrés mais simplement encodés en Base64. Cette méthode ne devrait donc être utilisée qu’avec HTTPS et non HTTP.

On retrouve cette méthode lors de la génération d’un token d’authentification sur les API de Cisco DNA Center par exemple. Ci-dessous un script que vous pouvez, encore une fois, testez par vous même grâce à la sandbox publique DNA Center accessible avec les paramètres suivants:

  • le FQDN du serveur est sandboxdnac.cisco.com et il est joignable en HTTPS
  • le chemin pour générer le token est /dna/system/api/v1/auth/token
  • la méthode à utiliser est POST
from requests import post
from base64 import b64encode
import json

def get_dnac_token(dnac_server: str, user: str, password: str):
    credentials = b64encode(f"{user}:{password}".encode()).decode()
    headers = {'Authorization': "Basic "+ credentials}
    resp = post(f'https://{dnac_server}/dna/system/api/v1/auth/token', json="", headers=headers)
    if resp.status_code != 200:
        raise ConnectionError(f'POST /dna/system/api/v1/auth/token {resp.status_code}')
    return({resp.json()["Token"]})

if __name__ == '__main__':
    token_dnac = get_dnac_token("sandboxdnac.cisco.com", "devnetuser", "Cisco123!")
    print(f"\n[-] Authentication Successful !\n[-] Authentication Token:\n{token_dnac}\n")

API avec authentification via API Key

Dans ce mode d’authentification, on commence par générer une clé API (=API Key) depuis le portail d’administration de la solution. Cette clé sera ensuite utilisée pour authentifier les requêtes API envoyées vers le serveur. Le gros avantage, c’est que les identifiants, utilisateur et mot de passe, ne sont plus envoyés au travers du réseau.

C’est le mode d’authentification utilisé par les API Meraki par exemple. Vous pouvez le tester sur l’instance Meraki de démonstration disponible avec ces paramètres:

  • FQDN du serveur n149.meraki.com joignable en HTTPS,
  • API Key pour authentifier les requêtes: 6bec40cf957de430a6f1f2baa056b99a4fac9ea0
  • Identifiants de connexion au portail Meraki: devenetmeraki@cisco.com et ilovemeraki

Et voici un script Python qui utilise ces paramètres pour lister les organisations auxquelles l’utilisateur a accès:

from requests import get
from json import dumps

BASE_URL = "https://n149.meraki.com/api/v0/"
API_KEY = "6bec40cf957de430a6f1f2baa056b99a4fac9ea0"

def list_organizations(base_url = BASE_URL, api_key = API_KEY):
    payload = {}
    headers = {'X-Cisco-Meraki-API-Key': api_key}
    url = base_url + "organizations"

    response = get(url, headers=headers, data = payload)
    return(response.json())

if __name__ == '__main__':
    print(dumps(list_organizations(), indent=2))

Voilà qui clôt ce premier article sur les APIS. Si le sujet vous intéresse, vous pouvez regarder le mode d’authentification OAuth 2.0 qui est très utilisé (APIs Google, Aruba Central, HERE Maps, eBay, etc.).

Votre commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l’aide de votre compte WordPress.com. Déconnexion /  Changer )

Photo Google

Vous commentez à l’aide de votre compte Google. Déconnexion /  Changer )

Image Twitter

Vous commentez à l’aide de votre compte Twitter. Déconnexion /  Changer )

Photo Facebook

Vous commentez à l’aide de votre compte Facebook. Déconnexion /  Changer )

Connexion à %s