Conception de l'authentification pour l'API REST


11

Je travaille sur une API pour un service REST que je vais à la fois produire et consommer. J'ai passé ces derniers jours à essayer de comprendre comment gérer correctement l'authentification, et je pense que j'ai finalement trouvé quelque chose.

Je viens avec cela sur la base des faits suivants sur la pile d'applications:

  1. Le client et le serveur sont en .NET4 (partie client dans le profil client)
  2. Le serveur expose à l'aide de WCF REST
  3. Je ne veux vraiment pas garder le nom d'utilisateur et le mot de passe en mémoire dans l'application

À partir de 3, je voulais utiliser une forme d'authentification par jeton, afin qu'après vérification des informations d'identification par le serveur, le client récupère un jeton à utiliser dans le reste de l'application (cela me permettra de faire d'autres choses, telles que temporisation des utilisateurs, possibilité de déplacer les utilisateurs de manière transparente entre les versions Web et de bureau, etc.). Après avoir compris comment rendre les appels rejouables et inviolables, j'ai trouvé ce qui suit:

  1. Avant que le client ne tente de s'authentifier, il génère une paire de clés Diffie-Hellman à l'aide de la ECDiffieHellmanCngclasse.
  2. Il envoie la partie publique de la paire de clés sur le câble avec le nom d'utilisateur et le mot de passe (via HTTPS bien sûr).
  3. Le serveur authentifie la combinaison nom d'utilisateur / mot de passe. En cas de succès, il procède ensuite comme suit:
    1. Crée un jeton de session unique
    2. Génère sa propre paire de clés DH et calcule le secret partagé à partir de la clé publique fournie par le client
    3. Prend note du jeton de session, du secret partagé, de l'utilisateur et de l'heure de la "dernière action" (utilisée pour une fenêtre d'expiration continue) dans sa base de données
    4. Renvoie le jeton de session, sa clé DH publique et un message de réussite d'authentification
  4. Le client prend la clé DH de la réponse, calcule le secret partagé et stocke le jeton et le secret en mémoire.

À partir de ce moment, la combinaison jeton / secret de session fonctionne comme la plupart des autres API REST, la demande étant empreinte digitale et horodatée, puis une sorte de HMAC est générée. Chaque fois qu'un client exécute une action contre le serveur, il vérifie la paire jeton / secret, autorise l'action si elle est valide et non expirée, et met à jour le dernier enregistrement d'action de la session.

Je ne vois pas de défauts évidents et est probablement trop conçu pour cela, mais je dois apprendre à le faire à un moment donné. Le HMAC empêche les attaques de rejeu, la négociation DH aide à prévenir les attaques MITM (je ne peux pas penser à une attaque réalisable du haut de ma tête entre HMAC / DH).

Des trous que n'importe qui peut percer?


Je ne vois pas comment la génération des clés DH ajoute une quelconque sécurité par rapport à la simple utilisation de HTTPS partout et à l'utilisation d'un cookie de session ancien. Lorsqu'il est utilisé correctement, HTTPS protège déjà contre les attaques de l'homme du milieu et de la relecture.
Lie Ryan

Réponses:


5

Plutôt que d'inventer la vôtre, vous devriez envisager de lire l'API OpenAM et de l'emprunter.

http://forgerock.com/openam.html

Le wiki OpenAM est particulièrement utile

https://wikis.forgerock.org/confluence/display/openam/Home

Vous n'avez pas besoin d'utiliser leurs composants. Mais si vous utilisez leur API, vous constaterez que votre vie sera plus simple à long terme.


Hmm, ça n'a pas l'air mal, une chose qui m'empêche de l'utiliser dans ce cas: nous sommes une boutique .Net. De plus, il n'y a pas grand-chose à utiliser avec le côté serveur WCF. Le seul lien non-spam que j'ai pu trouver sur Google indique l'utilisation de WIF et de WS-Federation.
Matt Sieker

1
@Matt Sieker: "Vous n'avez pas besoin d'utiliser leurs composants". Veuillez lire leur API au lieu d'inventer la vôtre.
S.Lott

Ah, je pense que je vois ce que vous voulez dire, les exigences de rappel. C'est intéressant, je pourrais y réfléchir davantage, sinon pour ce projet, pour les futurs. Au lieu de faire l'auth comme un seul morceau atomique, brisez-le légèrement, afin que le serveur puisse contrôler ce dont il a besoin du client ...
Matt Sieker

Au départ, nous avons lancé les nôtres, puis nous sommes passés à OpenAM il y a plusieurs années chez IG Group. Très satisfait du produit open source.
Robert Morschel

2

Je suis d'accord à 100% avec @ S.Lott que vous ne voulez pas rouler le vôtre. Je suggère de chercher une autre alternative: le service de contrôle d'accès Windows Azure (ACS). ACS coûte de l'argent, mais il est très bon marché (10 000 transactions pour 0,01 $) et une bonne partie de l'infrastructure est gérée. Le WIF est exploité sur le client.

Il s'agit également d'une solution basée sur des normes / revendications - qui fait fureur. Consultez cet article sur l'utilisation conjointe de WCF et REST et ACS .

Si vous pensez à l'avenir, c'est également un mécanisme qui peut évoluer avec vous - car vous avez des applications mobiles en dehors du pare-feu, des partenaires, etc. Même si vous ne voulez pas l'utiliser car il ajoute une dépendance en dehors de votre pare-feu, vous pouvez le vérifier pour des idées. Très lisse.

Bonne chance! -Facture

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.