web-dev-qa-db-fra.com

REST Authentification API pour application web et application mobile

J'ai du mal à décider comment implémenter l'authentification pour une API RESTful qui sera sécurisée pour la consommation à la fois par une application Web et une application mobile.

Tout d'abord, j'ai pensé à enquêter sur l'authentification de base HTTP sur HTTPS en option. Cela fonctionnerait bien pour une application mobile, où le nom d'utilisateur et le mot de passe pourraient être stockés en toute sécurité dans le trousseau du système d'exploitation et ne pourraient pas être interceptés en transit car la demande serait via HTTPS. Il est également élégant pour l'API car il sera complètement sans état. Le problème est lié à l'application Web. Il n'y aura pas accès à un tel trousseau pour stocker le nom d'utilisateur et le mot de passe, donc j'aurais besoin d'utiliser un cookie ou localStorage, mais alors je stocke les détails privés de l'utilisateur dans un endroit facilement accessible.

Après plus de recherches, j'ai trouvé beaucoup de discussions sur l'authentification HMAC. Le problème que je vois avec cette approche est qu'il doit y avoir un secret partagé que seuls le client et le serveur connaissent. Comment puis-je obtenir ce secret par utilisateur pour un utilisateur particulier dans l'application Web, sauf si j'ai un point de terminaison api/login qui prend le nom d'utilisateur/mot de passe et rend le secret à stocker dans un cookie? à utiliser dans les demandes futures. Cependant, cela introduit un état dans l'API.

Pour lancer une autre clé dans les travaux, j'aimerais pouvoir restreindre l'API à certaines applications (ou, pour pouvoir empêcher certaines applications d'utiliser l'API). Je ne vois pas comment cela serait possible avec l'application Web entièrement publique.

Je ne veux pas vraiment implémenter OAuth. C'est probablement exagéré pour mes besoins.

J'ai l'impression de ne pas bien comprendre HMAC, donc j'accueillerais volontiers une explication et comment je pourrais l'implémenter en toute sécurité avec une application web et une application mobile.

Mise à jour

J'ai fini par utiliser HTTP Basic Auth, mais au lieu de fournir le nom d'utilisateur et le mot de passe réels à chaque demande, un point de terminaison a été implémenté pour échanger le nom d'utilisateur et le mot de passe contre une clé d'accès qui est ensuite fournie pour chaque demande authentifiée. Élimine le problème de stockage du nom d'utilisateur et du mot de passe dans le navigateur, mais bien sûr, vous pouvez toujours pêcher le jeton si vous avez accès à la machine et l'utilisez. Avec le recul, j'aurais probablement regardé OAuth plus loin, mais c'est assez compliqué pour les débutants.

51
maknz

Vous devez utiliser OAuth2. Voici comment:

1) Application mobile

Les informations d'identification du client de l'application mobile lors de votre déclaration. Il utilise ensuite "Grant Owner Password Credentials Grant" (voir http://tools.ietf.org/html/rfc6749#section-4. ) pour envoyer ces informations d'identification. À son tour, il obtient un jeton (porteur) qu'il peut utiliser dans les demandes suivantes.

2) Site Web

Le site Web utilise "Authorization Code Grant" (voir http://tools.ietf.org/html/rfc6749#section-4.1 ):

  1. Le site Web voit une demande non autorisée et redirige le navigateur vers le point de terminaison d'autorisation HTML dans l'api REST.

  2. L'utilisateur s'authentifie avec le service REST

  3. Le site REST redirige l'utilisateur vers le site Web avec un jeton d'accès dans l'URL.

  4. Le site Web appelle REST site et échange le jeton d'accès en jeton d'autorisation.

Ici, après que le site Web utilise le jeton d'autorisation pour accéder au service REST (au nom de l'utilisateur final) - généralement en incluant le jeton en tant que jeton "porteur" dans l'en-tête d'autorisation HTTP.

Ce n'est pas sorcier, mais cela prend du temps à comprendre complètement.

3) Limiter l'accès à l'API pour certaines applications

Dans OAuth2, chaque client reçoit un ID client et un secret client (ici "client" est votre application mobile ou votre site Web). Le client doit envoyer ces informations d'identification lors de l'autorisation. Votre service REST peut l'utiliser pour valider le client appelant

24
Jørn Wildt

Une façon de résoudre le problème de l'authentification des utilisateurs auprès de l'API consiste à demander un jeton d'authentification à l'API lorsque l'utilisateur se connecte. Ce jeton peut ensuite être utilisé pour les demandes suivantes. Vous avez déjà abordé cette approche - c'est assez solide.

En ce qui concerne la restriction de certaines applications Web. Vous souhaiterez que chaque application Web s'identifie à chaque demande et que cette authentification soit effectuée dans votre implémentation d'API. Assez simple.

2
Dave

J'ai résolu cela pour ma propre API assez facilement et en toute sécurité sans avoir besoin d'exposer les informations d'identification du client.

J'ai également divisé le problème en 2 parties. Authentification API - est-ce une demande valide d'une entité reconnue (site Web ou application native). L'autorisation API est cette entité autorisée à utiliser ce point de terminaison particulier et ce verbe HTTP.

L'autorisation est codée dans l'API à l'aide d'une liste de contrôle d'accès et des autorisations et paramètres utilisateur qui sont définis dans le code, la configuration et la base de données de l'API selon les besoins. Une simple instruction if dans l'API peut tester l'autorisation et renvoyer la réponse appropriée (non autorisée ou les résultats du traitement de l'appel API).

L'authentification consiste maintenant simplement à vérifier si l'appel est authentique. Pour ce faire, j'émets des certificats auto-signés aux clients. Un appel à l'API est effectué depuis leur serveur quand ils le souhaitent - généralement lorsqu'ils génèrent leur première page (ou lorsqu'ils effectuent leurs propres vérifications de connexion à l'application). Cet appel utilise les certificats que j'ai fournis précédemment. Si de mon côté, je suis heureux que le certificat soit valide, je peux retourner un nonce et une clé API générée dans un temps limité. Cette clé est utilisée dans tous les appels ultérieurs à d'autres points de terminaison API, dans l'en-tête du support par exemple, et elle peut être stockée assez ouvertement dans un champ de formulaire HTML ou une variable javascript ou une variable dans une application.

Le nonce empêchera les attaques de relecture et la clé API peut être volée si quelqu'un le souhaite - il ne pourra pas continuer à l'utiliser après son expiration ou si le nonce change avant de passer le prochain appel.

Chaque réponse API contiendra le nonce suivant si le nonce ne correspond pas, il renverra une erreur d'authentification. En fait, le nonce ne correspond pas, je tue également la clé API. Cela forcera alors un véritable utilisateur de l'API à se réauthentifier à l'aide des certificats.

Tant que l'utilisateur final garde ces certificats en sécurité et n'expose pas la méthode qu'ils utilisent pour effectuer l'appel d'authentification initial (comme en faire une demande ajax qui peut être rejouée), les API sont agréables et sécurisées.

2
PCaligari