Où placer une clé API: un en-tête HTTP personnalisé VS l'en-tête d'autorisation avec un schéma personnalisé

18

Je conçois une API REST à l'aide d'une autorisation / authentification via une clé API.

J'ai essayé de trouver le meilleur endroit pour cela et j'ai découvert que beaucoup de gens suggèrent d'utiliser un en-tête HTTP personnalisé tel que ProjectName-Api-Key, par exemple:

ProjectName-Api-Key: abcde

mais il est également possible et idéologiquement correct d'utiliser l'en- Authorizationtête avec un schéma personnalisé, par exemple:

Authorization: ApiKey abcde

D'un autre côté, j'ai constaté qu'un schéma d'autorisation personnalisé peut être inattendu et non pris en charge par certains clients et conduit à un code personnalisé de toute façon, il est donc préférable d'utiliser un en-tête personnalisé car les clients n'ont aucune attente à ce sujet.

De quelle manière préféreriez-vous envoyer une clé API?

RomanG
la source
Les projets sous ma direction utilisent l'en- Authorization: Bearer <token>tête et il n'y a jamais eu un seul problème avec cela. Les jetons sont des JWT .
Andy
1
@DavidPacker Si je comprends bien, le Bearerschéma est utilisé exclusivement avec oAuth2. Son application séparément de oAuth semble une mauvaise utilisation. Pourquoi est-il correct d'utiliser ce schéma s'il n'y a pas d'oAuth? Au fait, j'ai eu du mal à choisir un type d'autorisation pour mon API. L'API ne sera disponible que pour un service de confiance, j'ai donc étudié le flux des informations d'identification client de oAuth2 et je n'ai trouvé aucun avantage par rapport à ApiKey dans mon cas.
RomanG
@DavidPacker J'ai alors compris que l'autorisation ApiKey pouvait être considérée comme une implémentation oAuth valide si elle ApiKeyétait renommée et interprétée comme Access Tokenaccordée au client sans délai d'expiration. C'est une sorte d'aspect philosophique, j'ai décidé de ne pas apporter de définitions complexes si mon cas peut être décrit en termes simples et j'ai décidé de simplement l'appeler "ApiKey". Si votre protocole implémente oAuth standart, je peux accepter l'utilisation Bearer, mais ce n'est pas le cas, je suppose que ce schéma ne peut pas être appliqué.
RomanG
2
Vous vous limitez trop. Le consommateur d'API s'en fiche de savoir si vous avez implémenté OAuth ou non. Ce qui leur importe, c'est la sécurité des jetons, que l'émission de jetons fonctionne et qu'ils puissent être correctement authentifiés. Ils recommandent d'utiliser Bearer directement dans la documentation JWT . JWT correspond parfaitement au schéma Bearer et je ne pourrais pas recommander davantage de JWT. Ils sont parfaits pour les applications REST car vous pouvez authentifier un utilisateur même sans toucher à la base de données - sauf si vous avez besoin d'une fonction de révocation de jetons.
Andy
1
(passez en voiture) ... veuillez prendre soin de savoir que les clés api sont des secrets partagés généralement partagés entre une partie de confiance configurée et un authentificateur, et non pour communiquer l'identité ou l'autorisation. Autrement dit, ils sont uniquement destinés à initier une prise de contact de sécurité, et non à représenter un résultat d'authentification. La clé API communique votre autorité à vous identifier par rapport à l'authentificateur de confiance du système. L'utilisation de la clé comme jeton pour contrôler l'accès sécurisé aux ressources est un mauvais juju
K. Alan Bates

Réponses:

13

Si vous utilisez l'autorisation, soyez cohérent

Certains diront que ce qui suit n'est pas nécessaire ( et il n'y a pas si longtemps, je serais d'accord avec eux ) mais, de nos jours, si nous utilisons l'en- Authorizationtête, nous devons informer le type du jeton, car les clés API ne sont pas auto-descriptives en soi 1 .

Pourquoi est-ce que je pense que c'est nécessaire et pourquoi je pense que c'est important? Parce que de nos jours, la prise en charge de différents protocoles d'authentification / autorisation est devenue un incontournable. Si nous prévoyons d'utiliser l'en- Authorizationtête pour tous ces protocoles, nous devons rendre notre service d'authentification cohérent. La manière de communiquer le type de jeton que nous envoyons et le protocole d'autorisation à appliquer doit également figurer dans l'en-tête.

Authorization: Basic xxxx
Authorization: Digest xxxx
Authorization: Bearer xxxx
Authorization: ApiKey-v1 xxxx
Authorization: ApiKey-v2 xxxx

Auparavant, je m'en fichais, mais après avoir travaillé avec des applications clientes dont les mises à jour n'étaient pas garanties (mobiles et capteurs principalement), j'ai commencé à le faire. J'ai commencé à être plus prudent dans la façon dont j'implémente la sécurité afin de pouvoir l'étendre sans déranger les clients et sans trop de douleur côté serveur.

Préoccupations

Les problèmes que j'ai rencontrés lors de la mise en œuvre de mes propres programmes sont similaires à celui commenté.

D'un autre côté, j'ai trouvé une considération qu'un schéma d'autorisation personnalisé peut être inattendu et non pris en charge par certains clients et conduit de toute façon au code personnalisé

Dites clients , dites bibliothèques, frameworks, proxy inverses .

Les avantages

Un avantage important est le cache. Les caches partagés ne mettront pas l'en-tête en cache (et c'est bien sûr bien sûr), sauf indication contraire.

Autorisation ou en-tête personnalisé?

D'après mon expérience, l'implémentation de mon propre Authorizationschéma m'a demandé autant de travail (ou plus) que l'implémentation d'en-têtes d'autorisation personnalisés, avec la légère différence d'avoir plus de liberté de conception et plus de contrôle sur le cache lorsque j'ai utilisé des en-têtes personnalisés. La raison est plutôt stupide, la plupart du temps j'ai le Cache-controlset no-cacheou no-store, ce qui me permet de rendre les appels au serveur plus déterministes (c'est important quand il s'agit de suivi et de test) quelle que soit la topologie du réseau.


1: Je trouve cette réponse très claire concernant les clés API

Laiv
la source
4
L'utilisation de X-est déconseillée à partir de 2012: stackoverflow.com/a/3561399/923720
Darkhogg
1
ops! Je ne savais pas. Édité et corrigé.
Laiv
Avant cette question, je pensais que la plupart des gens mettaient la clé API dans l'URL, mais utilisaient HTTPS pour la cacher. Bon de voir quelques alternatives. Par exemple, l' autorisation ou permet pourvues d'un contenu pamameter de requête: contentful.com/developers/docs/references/content-delivery-api/...
user949300
1
@ user949300 ... l'utilisation d'un secret partagé chiffré (par exemple une clé api dans uri sur ssl) est évidemment plus sûr que rien du tout, mais est facilement usurpable s'il est intercepté et ne fournit aucune granularité sur les identités. Je n'ai jamais utilisé api_keys pour autre chose que la communication de machine à machine où je fais correspondre le secret partagé entre les parties de confiance et les identités de machine sur liste blanche autorisées à agir avec ce secret partagé. Une fois la connexion de machine à machine effectuée, l'opérateur humain s'authentifie à l'aide d'autres moyens.
K. Alan Bates
@K. Alan Bates La plupart de mes interactions avec l'API concernaient des choses relativement "sans importance" comme les niveaux gratuits de géocodage, les rapports météorologiques, etc., où la clé API est plus pour limiter le débit que pour les secrets d'utilisateur sérieux. Donc, comme pour OP, cela dépend du niveau de sécurité requis.
user949300